C#代码的AES加密结果与Java AES加密的结果不同
我用Java编写了以下aes加密代码,我想用C#编写它,但它没有给出相同的输出。C#代码的AES加密结果与Java AES加密的结果不同,java,c#,encryption,aes,Java,C#,Encryption,Aes,我用Java编写了以下aes加密代码,我想用C#编写它,但它没有给出相同的输出。 Java代码 public String doEncryptString(String salt, String password,String token) throws CryptoException { try { Cipher cipher = Cipher.getInstance("AES"); SecretKeySpec secretKey
Java代码
public String doEncryptString(String salt, String password,String token) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec secretKeySpec = generateKeySpec(salt,password);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] inputBytes = token.getBytes();
byte[] outputBytes = cipher.doFinal(inputBytes);
return Base64Utils.encodeToString(outputBytes);
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
| IllegalBlockSizeException ex) {
throw new CryptoException("Error encrypting password", ex);
}
}
private SecretKeySpec generateKeySpec(String salt,String password) throws CryptoException{
try {
String generatedkey=salt+password;
byte[] key = generatedkey.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
return secretKeySpec;
} catch (NoSuchAlgorithmException | IOException ex) {
throw new CryptoException("Error encrypting password", ex);
}
}
这是我在C中尝试过的#
要加密的字符串/令牌:ZHKRIWB310xVVWG315PI7UZWU1V0YYL5WE9JLJava输出:eUjNH8kcgWtlEmuCFHMPwnCFWjy5Pye/gF+itrps1g8ajtaezqlzw/v7kEt2haG
我的C#代码输出:O8sKdJWH+XCOIBEXZPEWNxWQPWRC5B3ZSIHT8CFBI1EVR3PER9EQ39A5PMN
我不知道我做错了什么。任何帮助都将不胜感激。谢谢
更新
我向大家道歉。用C#翻译的代码运行良好。我错误地传递了不同的盐值。谢谢大家。Java代码的转换是什么 您还需要使用相同的模式和填充来获得相同的结果,这意味着在您的案例中使用ECB和PKCS7 Java似乎只提供PKCS5填充?但它似乎与PKCS7兼容?我不是Java开发人员,无法提供详细信息,但这里有一个讨论:他们说: 一些加密库(如Java中的SUN provider)表明 PKCS#5,其中应使用PKCS#7-“PKCS5Padding”应为 “PKCS7Padding”。很有可能,这是美国的遗产 仅使用8字节分组密码(如(三重)DES对称密码)的时间 密码是可用的
顺便说一句:对于生产,永远不要使用ECB模式,因为它不安全 Java代码的转换中有什么内容 您还需要使用相同的模式和填充来获得相同的结果,这意味着在您的案例中使用ECB和PKCS7 Java似乎只提供PKCS5填充?但它似乎与PKCS7兼容?我不是Java开发人员,无法提供详细信息,但这里有一个讨论:他们说: 一些加密库(如Java中的SUN provider)表明 PKCS#5,其中应使用PKCS#7-“PKCS5Padding”应为 “PKCS7Padding”。很有可能,这是美国的遗产 仅使用8字节分组密码(如(三重)DES对称密码)的时间 密码是可用的
顺便说一句:对于生产,永远不要使用ECB模式,因为它不安全 SHA1的结果在两种情况下都是一样的吗?一路上比较每个步骤和变量,毫无疑问AES实现没有问题,这就是你给它的,如果你再次以相同的值运行C#代码,它会给你不同的结果。@viveknuna不,它又会给你相同的结果。@John,我不确定事实上。SHA1的结果在两种情况下都是一样的吗?比较每一步和沿途的变量,毫无疑问AES实现没有错,这就是你给它的结果如果你以相同的值再次运行C#代码,它会给你不同的结果。@viveknuna不,它又给了同样的结果。@John,我不确定。对不起,我忘了加常量值。在Java代码中,转换值为“AES”。我也更新了这个问题。谢谢你的回复。由于您要求使用相同的模式和填充,我认为在Java中,AES的默认密码是AES/ECB/PKCS5Padding,请参见此处的讨论。我将研究PKCS5填充与PKCS7填充。很抱歉,我忘记添加常量值。在Java代码中,转换值为“AES”。我也更新了这个问题。谢谢你的回复。由于您要求使用相同的模式和填充,我认为在Java中,AES的默认密码是AES/ECB/PKCS5Padding,请参见此处的讨论。我将研究PKCS5填充和PKCS7填充。
public static string DoEncrypt(string salt, string password, string token)
{
var tdes = new AesManaged();
tdes.Key = GenerateKey(salt, password);
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform crypt = tdes.CreateEncryptor();
byte[] plain = Encoding.UTF8.GetBytes(token);
byte[] cipher = crypt.TransformFinalBlock(plain, 0, plain.Length);
return Convert.ToBase64String(cipher);
}
private static byte[] GenerateKey(string salt, string password)
{
string generatedkey = $"{salt}{password}";
var key = Encoding.UTF8.GetBytes(generatedkey);
var sha1 = SHA1Managed.Create();
key = sha1.ComputeHash(key);
return key.Take(16).ToArray(); // use only first 128 bit
}