I'm struggling with the PCLCryptho libraby, I can't get it working without retrieving the exception 'CryptographicException: Bad PKCS7 padding. Invalid length'. Running the code once is working, but running it multiple times after each other fails (with different input strings). The decryption takes place after a new instance of the program. I'm running this code on iOS with Xamarin Forms. Here's my code (I'm using the same VI each time and save the salt in the Settinsg for now):
public static string EncryptAnswer(string answer, string passWord)
{
try
{
var keyMaterial = CreateKey(passWord);
var cipherTextBuffer = GetBytes(answer);
var symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyMaterial);
using (var encryptor = WinRTCrypto.CryptographicEngine.CreateEncryptor(symmetricKey, GetBytes("vivivivivivivivi")))
{
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (var bWriter = new BinaryWriter(cs))
{
bWriter.Write(cipherTextBuffer, 0, cipherTextBuffer.Length);
cs.FlushFinalBlock();
}
}
return GetString(ms.ToArray());
}
}
}
catch (Exception e)
{
return string.Empty;
}
}
public static string DecryptAnswer(string encryptedAnswer, string passWord)
{
try
{
var cipherTextBuffer = GetBytes(encryptedAnswer);
var keyMaterial = CreateKey(passWord);
var symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyMaterial);
using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey, GetBytes("vivivivivivivivi")))
{
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
using (var binWriter = new BinaryWriter(cs))
{
binWriter.Write(cipherTextBuffer, 0, cipherTextBuffer.Length);
}
return GetString(ms.ToArray());
}
}
}
catch (Exception e)
{
}
return string.Empty;
}
public static byte[] CreateSalt()
{
var salt = WinRTCrypto.CryptographicBuffer.GenerateRandom(8);
CrossSettings.Current.AddOrUpdateValue("Salt", GetString(salt));
return salt;
}
private static byte[] GetSalt()
{
var saltString = CrossSettings.Current.GetValueOrDefault<string>("Salt");
var salt = GetBytes(saltString);
return salt;
}
private static byte[] CreateKey(string passWord)
{
var key = NetFxCrypto.DeriveBytes.GetBytes(passWord, GetSalt(), 1000, 32);
return key;
}
private static byte[] GetBytes(string str)
{
return Encoding.Unicode.GetBytes(str);
}
private static string GetString(byte[] bytes)
{
return Encoding.Unicode.GetString(bytes, 0, bytes.Length);
}
This seems to be equal to the answers and examples I found. Can someone tell me what's wrong?