.NET으로 암호화할 때의 주의점 ~ 이렇게 당신은 함정에 끼친다
소개
갑작스럽지만, 지금부터 닮은 코드를 2 종류 제시합니다.
둘 중 하나가 올바르게 움직이고 둘 중 하나가 런타임 오류입니다.
아
패턴 A.cspublic static class Cipher
{
private static readonly byte[] InitialzationVector = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly byte[] SharedKey = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly int BlockSize = InitialzationVector.Length * 8;
private static readonly int KeySize = SharedKey.Length * 8;
public static string Encrypt(string plainText)
{
using var rijndael = new RijndaelManaged
{
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
IV = InitialzationVector,
Key = SharedKey,
};
using var encryptor = rijndael.CreateEncryptor();
var bytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(encryptor.TransformFinalBlock(bytes, 0, bytes.Length));
}
public static string Decrypt(string cipherText)
{
using var rijndael = new RijndaelManaged
{
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
IV = InitialzationVector,
Key = SharedKey,
};
using var decryptor = rijndael.CreateDecryptor();
var bytes = Convert.FromBase64String(cipherText);
var plain = decryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(plain);
}
}
B
패턴 B.cspublic static class Cipher
{
private static readonly byte[] InitialzationVector = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly byte[] SharedKey = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly int BlockSize = InitialzationVector.Length * 8;
private static readonly int KeySize = SharedKey.Length * 8;
public static string Encrypt(string plainText)
{
using var rijndael = new RijndaelManaged
{
IV = InitialzationVector,
Key = SharedKey,
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
};
using var encryptor = rijndael.CreateEncryptor();
var bytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(encryptor.TransformFinalBlock(bytes, 0, bytes.Length));
}
public static string Decrypt(string cipherText)
{
using var rijndael = new RijndaelManaged
{
IV = InitialzationVector,
Key = SharedKey
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
};
using var decryptor = rijndael.CreateDecryptor();
var bytes = Convert.FromBase64String(cipherText);
var plain = decryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(plain);
}
}
결과
대답은 A가 올바르게 작동하는 것이 었습니다.
이상! !
... 그냥 외롭기 때문에 조금만 보충합니다.
덧붙여서 차이점은 BlockSize/KeySize를 먼저 초기화하는지, IV/Key를 먼저 초기화하는지의 차이 밖에 없습니다.
발생하는 예외
예외는 분명히 Decrypt 때 발생하는 것 같습니다.
그래서 공식 문서 을 보러 보면 분명히이 예외는 "inputCount 매개 변수의 길이가 입력 블록 크기로 나눌 수없는 경우"에 발생하는 것 같습니다.
그럼, 실제로 어떻게 되어 있는지 변수를 워치 해 보았습니다.
이미지에서는 닫고 있는 항목도 비교해 보았습니다만 같은 값이었습니다 😇
분명히 현지 시계에서는 보이지 않는 곳에서 아무것도 이상한 일을하는 것 같습니다.
어둠에 한쪽 다리를 밀어넣을 것 같아서 더 이상 쫓는 것을 그만뒀습니다.
결론
프로퍼티에 setter 를 마련하는 경우는, 이용자측이 어떤 순서로 값을 넣어 가는지는 부정이므로, 이러한 설계를 해서는 안됩니다.
이것은 분명히 나쁜 설계이므로 자신이 클래스를 만들 때는 조심합시다.
만약 만일 이런 제작을 해 버린 경우는, 문서에 반드시 호출 순서의 규약을 명기해 둡시다.
그것이 없으면 아무도 사양을 모르고, 당신의 생각하고있는 것 등 에스퍼가 아니기 때문에 아무도 알아주지 않습니다.
또, 요즘의 트렌드로 말하면 원래 Immutable 로 해 가자고 하는 흐름이므로, setter 등이라고 하는 제악의 근원인 기능을 사용해서는 안됩니다 (과격파).
자계도 담아 간에 명명해 둡시다.
Reference
이 문제에 관하여(.NET으로 암호화할 때의 주의점 ~ 이렇게 당신은 함정에 끼친다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Midoliy/items/df299337434d8c724cba
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public static class Cipher
{
private static readonly byte[] InitialzationVector = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly byte[] SharedKey = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly int BlockSize = InitialzationVector.Length * 8;
private static readonly int KeySize = SharedKey.Length * 8;
public static string Encrypt(string plainText)
{
using var rijndael = new RijndaelManaged
{
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
IV = InitialzationVector,
Key = SharedKey,
};
using var encryptor = rijndael.CreateEncryptor();
var bytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(encryptor.TransformFinalBlock(bytes, 0, bytes.Length));
}
public static string Decrypt(string cipherText)
{
using var rijndael = new RijndaelManaged
{
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
IV = InitialzationVector,
Key = SharedKey,
};
using var decryptor = rijndael.CreateDecryptor();
var bytes = Convert.FromBase64String(cipherText);
var plain = decryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(plain);
}
}
public static class Cipher
{
private static readonly byte[] InitialzationVector = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly byte[] SharedKey = Encoding.UTF8.GetBytes(@"xxxxxxxxxxxxxxxx");
private static readonly int BlockSize = InitialzationVector.Length * 8;
private static readonly int KeySize = SharedKey.Length * 8;
public static string Encrypt(string plainText)
{
using var rijndael = new RijndaelManaged
{
IV = InitialzationVector,
Key = SharedKey,
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
};
using var encryptor = rijndael.CreateEncryptor();
var bytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(encryptor.TransformFinalBlock(bytes, 0, bytes.Length));
}
public static string Decrypt(string cipherText)
{
using var rijndael = new RijndaelManaged
{
IV = InitialzationVector,
Key = SharedKey
BlockSize = BlockSize,
KeySize = KeySize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
};
using var decryptor = rijndael.CreateDecryptor();
var bytes = Convert.FromBase64String(cipherText);
var plain = decryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(plain);
}
}
대답은 A가 올바르게 작동하는 것이 었습니다.
이상! !
... 그냥 외롭기 때문에 조금만 보충합니다.
덧붙여서 차이점은 BlockSize/KeySize를 먼저 초기화하는지, IV/Key를 먼저 초기화하는지의 차이 밖에 없습니다.
발생하는 예외
예외는 분명히 Decrypt 때 발생하는 것 같습니다.
그래서 공식 문서 을 보러 보면 분명히이 예외는 "inputCount 매개 변수의 길이가 입력 블록 크기로 나눌 수없는 경우"에 발생하는 것 같습니다.
그럼, 실제로 어떻게 되어 있는지 변수를 워치 해 보았습니다.
이미지에서는 닫고 있는 항목도 비교해 보았습니다만 같은 값이었습니다 😇
분명히 현지 시계에서는 보이지 않는 곳에서 아무것도 이상한 일을하는 것 같습니다.
어둠에 한쪽 다리를 밀어넣을 것 같아서 더 이상 쫓는 것을 그만뒀습니다.
결론
프로퍼티에 setter 를 마련하는 경우는, 이용자측이 어떤 순서로 값을 넣어 가는지는 부정이므로, 이러한 설계를 해서는 안됩니다.
이것은 분명히 나쁜 설계이므로 자신이 클래스를 만들 때는 조심합시다.
만약 만일 이런 제작을 해 버린 경우는, 문서에 반드시 호출 순서의 규약을 명기해 둡시다.
그것이 없으면 아무도 사양을 모르고, 당신의 생각하고있는 것 등 에스퍼가 아니기 때문에 아무도 알아주지 않습니다.
또, 요즘의 트렌드로 말하면 원래 Immutable 로 해 가자고 하는 흐름이므로, setter 등이라고 하는 제악의 근원인 기능을 사용해서는 안됩니다 (과격파).
자계도 담아 간에 명명해 둡시다.
Reference
이 문제에 관하여(.NET으로 암호화할 때의 주의점 ~ 이렇게 당신은 함정에 끼친다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Midoliy/items/df299337434d8c724cba
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(.NET으로 암호화할 때의 주의점 ~ 이렇게 당신은 함정에 끼친다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Midoliy/items/df299337434d8c724cba텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)