使用 SHA256 的 AES 加密
AES encryption with SHA256
我需要的是使用 Sha256 密钥在 AES 中加密字符串
java 相同加密的代码是
private static final String AES_KEY = "something";
String encodedText = null;
try {
final MessageDigest md = MessageDigest.getInstance("SHA-256");
final byte[] digestOfPassword = md.digest(AES_KEY.getBytes("utf-8"));
final SecretKey key = new SecretKeySpec(digestOfPassword, "AES");
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final IvParameterSpec iv = new IvParameterSpec(new byte[16]);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = orignalText.getBytes("utf-8");
final byte[] encodeTextBytes = cipher.doFinal(plainTextBytes);
encodedText = new Base64().encodeToString(encodeTextBytes);
}
但我需要 C# 中的等价物,我能够开发成
private static byte[] ivBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
// keyBytes
private static byte[] keyBytes = new byte[] { 0x60, 0x3d, (byte) 0xeb,
0x10, 0x15, (byte) 0xca, 0x71, (byte) 0xbe, 0x2b, 0x73,
(byte) 0xae, (byte) 0xf0, (byte) 0x85, 0x7d, 0x77, (byte) 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, (byte) 0xd7, 0x2d,
(byte) 0x98, 0x10, (byte) 0xa3, 0x09, 0x14, (byte) 0xdf,
(byte) 0xf4 };
public string AES_Encrypt(string ToBeEncrypted, string password)
{
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
// It is equal in java
/// Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
SHA256 sha = new SHA256Managed();
aes.Key = sha.ComputeHash(Encoding.UTF8.GetBytes(password));
aes.IV = ivBytes;
ICryptoTransform encrypto = aes.CreateEncryptor();
byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(ToBeEncrypted);
byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);
string enc = BitConverter.ToString(CipherText).Replace("-", string.Empty);
return Convert.ToBase64String(CipherText) + "----"+ Convert.ToBase64String(ASCIIEncoding.UTF8.GetBytes(enc));
}
我对 AES 中的 SHA256 和 PKCS5Padding 术语感到非常困惑。我使用了用于加密的相同密钥,但无法获得与 java 代码给出的相同输出。
在 Java 中,您使用的是 empty/zero: IV
final IvParameterSpec iv = new IvParameterSpec(new byte[16]);
在 C# 中,您使用的是 000102030405060708090A0B0C0D0E0F
private static byte[] ivBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
由于您同时执行加密并且比较加密结果,这将对输出产生巨大影响。 (如果一个解密另一个加密错误将被限制在前 16 个字节)。
我也不得不指出 SHA-2-256 是一个糟糕的密钥派生函数。如果你想把密码变成密钥,你应该使用真正的 KDF,比如 PBKDF2(password-based 密钥派生函数(版本)2)。在 .NET 中,它被实现为 Rfc2898DeriveBytes
。在 Java 中似乎是 "PBKDF2WithHmacSHA1" SecretKeyFactory
.
我需要的是使用 Sha256 密钥在 AES 中加密字符串 java 相同加密的代码是
private static final String AES_KEY = "something";
String encodedText = null;
try {
final MessageDigest md = MessageDigest.getInstance("SHA-256");
final byte[] digestOfPassword = md.digest(AES_KEY.getBytes("utf-8"));
final SecretKey key = new SecretKeySpec(digestOfPassword, "AES");
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final IvParameterSpec iv = new IvParameterSpec(new byte[16]);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = orignalText.getBytes("utf-8");
final byte[] encodeTextBytes = cipher.doFinal(plainTextBytes);
encodedText = new Base64().encodeToString(encodeTextBytes);
}
但我需要 C# 中的等价物,我能够开发成
private static byte[] ivBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
// keyBytes
private static byte[] keyBytes = new byte[] { 0x60, 0x3d, (byte) 0xeb,
0x10, 0x15, (byte) 0xca, 0x71, (byte) 0xbe, 0x2b, 0x73,
(byte) 0xae, (byte) 0xf0, (byte) 0x85, 0x7d, 0x77, (byte) 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, (byte) 0xd7, 0x2d,
(byte) 0x98, 0x10, (byte) 0xa3, 0x09, 0x14, (byte) 0xdf,
(byte) 0xf4 };
public string AES_Encrypt(string ToBeEncrypted, string password)
{
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
// It is equal in java
/// Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
SHA256 sha = new SHA256Managed();
aes.Key = sha.ComputeHash(Encoding.UTF8.GetBytes(password));
aes.IV = ivBytes;
ICryptoTransform encrypto = aes.CreateEncryptor();
byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(ToBeEncrypted);
byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);
string enc = BitConverter.ToString(CipherText).Replace("-", string.Empty);
return Convert.ToBase64String(CipherText) + "----"+ Convert.ToBase64String(ASCIIEncoding.UTF8.GetBytes(enc));
}
我对 AES 中的 SHA256 和 PKCS5Padding 术语感到非常困惑。我使用了用于加密的相同密钥,但无法获得与 java 代码给出的相同输出。
在 Java 中,您使用的是 empty/zero: IV
final IvParameterSpec iv = new IvParameterSpec(new byte[16]);
在 C# 中,您使用的是 000102030405060708090A0B0C0D0E0F
private static byte[] ivBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
由于您同时执行加密并且比较加密结果,这将对输出产生巨大影响。 (如果一个解密另一个加密错误将被限制在前 16 个字节)。
我也不得不指出 SHA-2-256 是一个糟糕的密钥派生函数。如果你想把密码变成密钥,你应该使用真正的 KDF,比如 PBKDF2(password-based 密钥派生函数(版本)2)。在 .NET 中,它被实现为 Rfc2898DeriveBytes
。在 Java 中似乎是 "PBKDF2WithHmacSHA1" SecretKeyFactory
.