C#和OpenSSL:AES加密的输出不同
我正在尝试编写一个C#方法,它会像openssl二进制文件一样吐出相同的加密字符串(Base64),但是我很快就会把事情搞得一团糟.
很多终端输出和C#跟随……:P 我们将使用密码“123”加密字符串“a”的非常令人兴奋的例子. 首先是openssl,当我提供我的静态salt和密码时(这是理想运行命令的方式,也就是我希望我的C#输出匹配): dev@magoo ~# echo -n a | openssl enc -aes-128-cbc -S cc77e2a591358a1c -pass pass:123 -a -p salt=CC77E2A591358A1C key=7B2AD689138A44AD32297BBAAA5B0EEE iv =EC4F0416B2E9A9B2FEEF2E66FF982159 U2FsdGVkX1/Md+KlkTWKHOtnt1ftHSKyWiz6GxkBVck= 第二个是openssl,当我提供我的静态盐,以及从该盐派生的密钥和iv(来自第一个命令的输出的C P’d)但没有密码(因为即使文档说这将是一个不好的理念): dev@magoo ~# echo -n a | openssl enc -aes-128-cbc -S cc77e2a591358a1c -K 7b2ad689138a44ad32297bbaaa5b0eee -iv ec4f0416b2e9a9b2feef2e66ff982159 -a -p salt=E85778B7FFFFFFFF key=7B2AD689138A44AD32297BBAAA5B0EEE iv =EC4F0416B2E9A9B2FEEF2E66FF982159 62e3V+0dIrJaLPobGQFVyQ== 这让我很奇怪.将第一个命令中的“debug”输出(-p param)中的键值和iv值添加到同一个salt中,我会以某种方式获得不同的盐! (CC77E2A591358A1C vs E85778B7FFFFFFFF [这里的0xff的4个字节似乎很有趣]). 第三是我的申请的输出: dev@magoo ~# mono aestest.exe "a" "123" ==> INPUT : a ==> SECRET : 123 ==> SALT : cc77e2a591358a1c ==> KEY : 7b2ad689138a44ad32297bbaaa5b0eee ==> IV : ec4f0416b2e9a9b2feef2e66ff982159 ==> ENCRYPTED : 62e3V+0dIrJaLPobGQFVyQ== 因此,当我手动指定密钥和IV(然后以某种方式生成不同的盐)时,C#匹配openssl命令的输出,但这似乎是错误的.在我看来,C#应用程序的输出应该匹配第一组OpenSSL的输出,不应该吗? C#代码: public static string EncryptString(string plainText,string password) { byte[] salt = Encryption.GetStaticSalt(); byte[] key,iv; Encryption.DeriveKeyAndIV(password,salt,out key,out iv); var amAes = new AesManaged(); amAes.Mode = CipherMode.CBC; amAes.KeySize = 128; amAes.BlockSize = 128; amAes.Key = key; amAes.IV = iv; var icTransformer = amAes.CreateEncryptor(); var msTemp = new MemoryStream(); var csEncrypt = new CryptoStream(msTemp,icTransformer,CryptoStreamMode.Write); var sw = new StreamWriter(csEncrypt); sw.Write(plainText); sw.Close(); sw.Dispose(); csEncrypt.Clear(); csEncrypt.Dispose(); byte[] bResult = msTemp.ToArray(); string sResult = Convert.ToBase64String(bResult); if (System.Diagnostics.Debugger.IsAttached) { string debugDetails = ""; debugDetails += "==> INPUT : " + plainText + Environment.NewLine; debugDetails += "==> SECRET : " + password + Environment.NewLine; debugDetails += "==> SALT : " + Encryption.ByteArrayToHexString(salt) + Environment.NewLine; debugDetails += "==> KEY : " + Encryption.ByteArrayToHexString(amAes.Key) + " (" + amAes.KeySize.ToString() + ")" + Environment.NewLine; debugDetails += "==> IV : " + Encryption.ByteArrayToHexString(amAes.IV) + Environment.NewLine; debugDetails += "==> ENCRYPTED : " + sResult; Console.WriteLine(debugDetails); } return sResult; } private static string ByteArrayToHexString(byte[] bytes) { StringBuilder sbHex = new StringBuilder(); foreach (byte b in bytes) sbHex.AppendFormat("{0:x2}",b); return sbHex.ToString(); } public static byte[] GetStaticSalt() { // Just random bytes. return new byte[] { 0xcc,0x77,0xe2,0xa5,0x91,0x35,0x8a,0x1c }; } // largely hijacked from https://stackoverflow.com/a/8011654/97423 public static void DeriveKeyAndIV(string password,byte[] bSalt,out byte[] bKey,out byte[] bIV) { int keyLen = 16; int ivLen = 16; byte[] bPassword = Encoding.UTF8.GetBytes(password); using (var md5Gen = MD5.Create()) { List<byte> lstHashes = new List<byte>(keyLen + ivLen); byte[] currHash = new byte[0]; int preHashLength = bPassword.Length + bSalt.Length; byte[] preHash = new byte[preHashLength]; Buffer.BlockCopy(bPassword,preHash,bPassword.Length); Buffer.BlockCopy(bSalt,bPassword.Length,bSalt.Length); currHash = md5Gen.ComputeHash(preHash); lstHashes.AddRange(currHash); while (lstHashes.Count < (keyLen + ivLen)) { preHashLength = currHash.Length + password.Length + bSalt.Length; preHash = new byte[preHashLength]; Buffer.BlockCopy(currHash,currHash.Length); Buffer.BlockCopy(bPassword,currHash.Length,password.Length); Buffer.BlockCopy(bSalt,currHash.Length + password.Length,bSalt.Length); currHash = md5Gen.ComputeHash(preHash); lstHashes.AddRange(currHash); } bKey = new byte[keyLen]; bIV = new byte[ivLen]; lstHashes.CopyTo(0,bKey,keyLen); lstHashes.CopyTo(keyLen,bIV,ivLen); } } 我在这里遗漏了一些非常明显的东西,还是这个更微妙的东西?我环顾四周,看过很多关于C#,OpenSSL和AES的内容,但没有关于这个特定问题的内容……那么,halp? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |