[英]AES Decryption Using C#
我正在使用一個名為Zuul的基於Java的配置管理工具,它支持使用各種加密方案加密敏感配置信息。
我已將其配置為使用以下方案來獲取我的數據
AES(Bouncy Castle)
現在,在回讀我的配置數據時,我需要在使用之前解密信息,文檔提供了有關此主題的以下信息。
Jasypt(以及Zuul)生成的加密值以鹽為前綴(通常為8或16字節,具體取決於算法要求)。 然后它們是Base64編碼的。 解密結果是這樣的:
更多細節: Zull加密維基
基於以上細節,我寫了下面的代碼(我對安全性的了解非常有限)
public static string Decrypt(string cipher, string password)
{
const int saltLength = 16;
const int iterations = 1000;
byte[] cipherBytes = Convert.FromBase64String(cipher);
byte[] saltBytes = cipherBytes.Take(saltLength).ToArray();
byte[] encryptedBytes = cipherBytes.Skip(saltLength).ToArray();
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, saltBytes, iterations);
byte[] keyBytes = key.GetBytes(16);
AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider();
aesAlg.KeySize = 256;
aesAlg.BlockSize = 128;
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
MemoryStream msDecrypt = new MemoryStream(encryptedBytes);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
StreamReader srDecrypt = new StreamReader(csDecrypt);
return srDecrypt.ReadToEnd();
}
我將Zuul配置為使用以下密碼進行加密
SimplePassword
現在我有一個Zuul給我的加密字符串,我需要解密它
p8C9hAHaoo0F25rMueT0 + u0O6xYVpGIkjHmWqFJmTOvpV8 + cipoDFIUnaOFF5ElQ
當我嘗試使用上面的代碼解密此字符串時,我得到以下異常
System.Security.Cryptography.CryptographicException:填充無效,無法刪除。
正如我之前提到的,我對這個主題的了解是有限的,我無法弄清楚文檔中提供的信息是否不夠,如果我在編寫解密例程時做錯了什么,或者我應該使用充氣城堡解密也是如此。
任何幫助都將非常感激。
根據Zuul文檔,他們從密碼/鹽中獲取密鑰和iv。 因此,您應該派生256 + 128位(即48字節),並使用前32個字節作為密鑰,接下來的16個字節作為IV。 這應該在一個操作中完成,而不是隨后調用key.DeriveBytes。
我使用Bouncy Castle進行解密,因為Zuul也使用了它。
這是有效的代碼
public static string Decrypt(string cipher, string password)
{
const int saltLength = 16;
const int iterations = 1000;
const string algSpec = "AES/CBC/NoPadding";
const string algName = "PBEWITHSHA256AND128BITAES-CBC-BC";
byte[] cipherBytes = Convert.FromBase64String(cipher);
byte[] saltBytes = cipherBytes.Take(saltLength).ToArray();
byte[] encryptedBytes = cipherBytes.Skip(saltLength).ToArray();
char[] passwordChars = password.ToCharArray();
Asn1Encodable defParams = PbeUtilities.GenerateAlgorithmParameters(algName, saltBytes, iterations);
IWrapper wrapper = WrapperUtilities.GetWrapper(algSpec);
ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(algName, passwordChars, defParams);
wrapper.Init(false, parameters);
byte[] keyText = wrapper.Unwrap(encryptedBytes, 0, encryptedBytes.Length);
return Encoding.Default.GetString(keyText);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.