AES 加密 Windows Phone 8.1
AES Encryption Windows Phone 8.1
我需要对 Windows Phone 8.1 中的应用程序进行 128 位 AES 加密。我分别使用以下代码对数据进行加密和解密:
private string GetEncryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, null);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
private string GetDecryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, null);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
但是加密和解密似乎没有正常进行。它被加密为一些 unicode 字符并在解密时抛出崩溃:
Length is not a multiple of block size and no padding is
selected.\r\nParameter name: ciphertext
我在这里做错了什么?有人可以帮忙吗?
编辑
用了很多时间Google后,我发现了以下加密和解密的方法,但它们似乎也不起作用。
public string GetEncryptedContent(string input, string pass)
{
SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
CryptographicKey AES;
HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash Hash_AES = HAP.CreateHash();
string encrypted = "";
try
{
byte[] hash = new byte[32];
Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
byte[] temp;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);
Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
IBuffer Buffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(input));
encrypted = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(AES, Buffer, null));
return encrypted;
}
catch (Exception ex)
{
return null;
}
}
public string GetDecryptedContent(string input, string pass)
{
SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
CryptographicKey AES;
HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash Hash_AES = HAP.CreateHash();
string decrypted = "";
try
{
byte[] hash = new byte[32];
Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
byte[] temp;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);
Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
IBuffer Buffer = CryptographicBuffer.DecodeFromBase64String(input);
byte[] Decrypted;
CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(AES, Buffer, null), out Decrypted);
decrypted = Encoding.UTF8.GetString(Decrypted, 0, Decrypted.Length);
return decrypted;
}
catch (Exception ex)
{
return null;
}
}
编辑 2
终于设法让加密正常工作,但解密仍然无法正常工作,大概是因为我传递的编码不正确:
private string GetEncryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
byte[] iv = new byte[128 / 8]; // Adding this solved the encryption issue.
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
private string GetDecryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Convert.FromBase64String(content); // Believe this is where the issue is, but not able to figure it out.
byte[] iv = new byte[128 / 8]; // Added this to make the decryption work the same way.
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
我终于解决了这个问题。问题出在文本编码上。使用正确的编码解决了这个问题。下面的工作代码:
public static string EncryptAES(string content, string password)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
byte[] data = Encoding.UTF8.GetBytes(content);
byte[] iv = new byte[keyMaterial.Length];
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
public static string DecryptAES(string content, string password)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
byte[] data = Convert.FromBase64String(content);
byte[] iv = new byte[keyMaterial.Length];
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
WinRTCrypto
作为 PCLCrypto 的一部分可用。
我需要对 Windows Phone 8.1 中的应用程序进行 128 位 AES 加密。我分别使用以下代码对数据进行加密和解密:
private string GetEncryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, null);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
private string GetDecryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, null);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
但是加密和解密似乎没有正常进行。它被加密为一些 unicode 字符并在解密时抛出崩溃:
Length is not a multiple of block size and no padding is selected.\r\nParameter name: ciphertext
我在这里做错了什么?有人可以帮忙吗?
编辑
用了很多时间Google后,我发现了以下加密和解密的方法,但它们似乎也不起作用。
public string GetEncryptedContent(string input, string pass)
{
SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
CryptographicKey AES;
HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash Hash_AES = HAP.CreateHash();
string encrypted = "";
try
{
byte[] hash = new byte[32];
Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
byte[] temp;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);
Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
IBuffer Buffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(input));
encrypted = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(AES, Buffer, null));
return encrypted;
}
catch (Exception ex)
{
return null;
}
}
public string GetDecryptedContent(string input, string pass)
{
SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
CryptographicKey AES;
HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash Hash_AES = HAP.CreateHash();
string decrypted = "";
try
{
byte[] hash = new byte[32];
Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
byte[] temp;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);
Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
IBuffer Buffer = CryptographicBuffer.DecodeFromBase64String(input);
byte[] Decrypted;
CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(AES, Buffer, null), out Decrypted);
decrypted = Encoding.UTF8.GetString(Decrypted, 0, Decrypted.Length);
return decrypted;
}
catch (Exception ex)
{
return null;
}
}
编辑 2
终于设法让加密正常工作,但解密仍然无法正常工作,大概是因为我传递的编码不正确:
private string GetEncryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
byte[] iv = new byte[128 / 8]; // Adding this solved the encryption issue.
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
private string GetDecryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Convert.FromBase64String(content); // Believe this is where the issue is, but not able to figure it out.
byte[] iv = new byte[128 / 8]; // Added this to make the decryption work the same way.
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
我终于解决了这个问题。问题出在文本编码上。使用正确的编码解决了这个问题。下面的工作代码:
public static string EncryptAES(string content, string password)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
byte[] data = Encoding.UTF8.GetBytes(content);
byte[] iv = new byte[keyMaterial.Length];
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
public static string DecryptAES(string content, string password)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
byte[] data = Convert.FromBase64String(content);
byte[] iv = new byte[keyMaterial.Length];
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
WinRTCrypto
作为 PCLCrypto 的一部分可用。