1
C#에서 데이터를 암호화하고 해독하는 간단한 클래스를 테스트하려고합니다.여백이 잘못되어 제거 할 수 없습니다. AES PKCS7
`
{ [TestFixture]
public class CryptTest
{
[Test]
public void TestMethod()
{
String text = "Hello World!";
String crypt = EncryptionService.Encrypt(text, Config.KEY_STRING);
Console.WriteLine(crypt);
String clear = EncryptionService.Decrypt(crypt, Config.KEY_STRING);
Console.WriteLine(clear);
Assert.That(clear, Is.EqualTo(text));
}
`그러나, 나는 다음과 같은 예외가 수신하고
: :이 테스트중인 클래스가 StackTrace " at System.Security.Cryptography.CapiSymmetricAlgorithm.DepadBlock(Byte[] block, Int32 offset, Int32 count)\r\n at System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)\r\n at System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.StreamReader.ReadBuffer()\r\n at System.IO.StreamReader.ReadToEnd()\r\n at InsuranceMidAm.Services.EncryptionService.Decrypt(String cipher, String key) in C:\\Visual Studio Projects\\InsuranceMidAm\\InsuranceMidAm\\Services\\EncryptionService.cs:line 72\r\n at InsuranceMidAm.Tests.CryptTest.TestMethod() in C:\\Visual Studio Projects\\InsuranceMidAm\\InsuranceMidAm.Tests\\CryptTest.cs:line 20" string
: 스택과
Message: System.Security.Cryptography.CryptographicException : Padding is invalid and cannot be removed.
을
namespace InsuranceMidAm.Services
{
public class EncryptionService
{
// Reference: https://stackoverflow.com/questions/273452/using-aes-encryption-in-c-sharp
public static String Encrypt(String text, String key)
{
byte[] value = UTF8Encoding.UTF8.GetBytes(text);
byte[] crypt;
byte[] iv;
using (Aes myAes = Aes.Create())
{
myAes.KeySize = 256;
myAes.Mode = CipherMode.CBC;
myAes.Key = HexToBin(key);
myAes.GenerateIV();
myAes.Padding = PaddingMode.PKCS7;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, myAes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(value, 0, value.Length);
cs.FlushFinalBlock();
crypt = ms.ToArray();
}
}
iv = myAes.IV;
myAes.Clear();
}
return ByteArrayToString(crypt) + ":" + ByteArrayToString(iv);
}
public static string Decrypt(String cipher, String key)
{
String outputString = "";
byte[] ivBytes = HexToBin(getIV(cipher));
byte[] valBytes = HexToBin(getSSN(cipher));
using (Aes myAes = Aes.Create())
{
int size = valBytes.Count();
myAes.KeySize = 256;
myAes.Mode = CipherMode.CBC;
myAes.Key = HexToBin(key);
myAes.IV = ivBytes;
myAes.Padding = PaddingMode.PKCS7;
char[] output = new char[256];
ICryptoTransform myDecrypter = myAes.CreateDecryptor(myAes.Key, myAes.IV);
using (MemoryStream memory = new MemoryStream(ivBytes))
{
using (CryptoStream cryptStream = new CryptoStream(memory, myDecrypter, CryptoStreamMode.Read))
{
using (StreamReader reader = new StreamReader(cryptStream))
{
outputString = reader.ReadToEnd();
}
return outputString;
}
}
}
}
private static byte[] HexToBin(String hexString)
{
int charCount = hexString.Length;
byte[] output = new byte[charCount/2];
for (int i = 0; i < charCount; i += 2)
{
output[i/2] = Convert.ToByte(hexString.Substring(i, 2), 16);
}
return output;
}
private static String getSSN(String cipher)
{
int delimiterIndex = cipher.IndexOf(":");
String SSN = cipher.Substring(0, delimiterIndex);
return SSN;
}
private static String getIV(String cipher)
{
int delimiterIndex = cipher.IndexOf(":");
String IV = cipher.Substring(delimiterIndex + 1);
return IV;
}
// Reference: https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa
private static string ByteArrayToString(byte[] ba)
{
string hex = BitConverter.ToString(ba);
return hex.Replace("-", "");
}
}
}
라인 (73) (예외가 발생되는 경우)를 해독 방법의에서는 StreamReader에 대한 사용하여 블록의 끝 :
using (StreamReader reader = new StreamReader(cryptStream))
{
outputString = reader.ReadToEnd();
}
내가
following question를 참조하지만, 내 문제를 해결하지 못했습니다.
원래 데이터는 PHP 응용 프로그램에서 암호화되었으며 C# 응용 프로그램을 사용하여 암호 해독되었습니다 (위와 거의 동일한 해독 방법 사용). 이제는 C#을 사용하여 데이터를 암호화하고 해독하려고합니다. 그러나 나는 여전히 PHP를 사용하여 암호화 된 기존 데이터를 적절하게 해독 할 수 있어야하므로 decrypt 메서드를 너무 많이 수정하지 않을 것입니다.
모든 조언을 주시면 감사하겠습니다. 대신 실제로 암호화 된 바이트,
ICryptoTransform myDecrypter = myAes.CreateDecryptor(myAes.Key, myAes.IV);
using (MemoryStream memory = new MemoryStream(ivBytes))
당신은 해독 당신의 IV 값을 전달 :
고맙습니다. 그것을 해결했습니다. 다양한 실수가 같은 예외를 일으킬 수있는 것처럼 보입니다. 큰 관찰. :) – KellyMarchewa
@Kelly 그렇습니다. 해독 된 텍스트의 끝 부분을 잘못 잡아 먹는 실수는 잘못된 유형의 패딩을 사용하는 것과 마찬가지로 '잘못된 채움'예외를 발생시킵니다. 어느 쪽이든, 해독 코드는 올바른 패딩을 인식 할 수 없으며 예외를 throw합니다. – rossum
@KellyMarchewa 임의의 생성 된 값을 암호 해독 (IV)에 전달하므로 모든 종류의 오류가 발생할 수 있습니다. 운이 좋고 패딩이 정확하다면 - 예를 들어 쓰레기를 해독 할 수 있습니다. 슈퍼 운이 좋으면 생성 된 IV가 암호화 된 데이터와 동일합니다. 올바르게 해독 될 수도 있습니다. – Evk