我正在尝试将现有的C#加密方法转换为Java,但遇到了如下障碍
例如,当我使用C#加密基本字符串“ 12345”时,我得到此输出 8ZQZEUrctqP1PMmQxVtCcA ==
当我用java加密相同的字符串时,我得到了 jkEZp2cfeGXVE / IxIW6X3g ==
private static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations,
string initVector, int keySize)
{
try
{
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = password.GetBytes(keySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string cipherText = Convert.ToBase64String(cipherTextBytes);
return cipherText;
}
catch (Exception execp)
{
MessageBox.Show(string.Format("Exception in Encrypt function\r\nError: {0}", execp.Message));
return "";
}
}
private static string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations,
string initVector, int keySize)
{
try
{
if (cipherText == string.Empty)
return "";
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = password.GetBytes(keySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
return plainText;
}
catch (Exception execp)
{
MessageBox.Show(string.Format("Exception in Decrypt function\r\nError: {0}", execp.Message));
return "";
}
}
public static string ProtectPassword(string plainText)
{
try
{
const string passPhrase = "Ydfv324232r!23%47%7^&ex>,1"; // can be any string
const string saltValue = "s@1tValue"; // can be any string
const string hashAlgorithm = "SHA1"; // can be "MD5"
const int passwordIterations = 101; // can be any number
const string initVector = "@1B2vQ94eZF6g7H1"; // must be 16 bytes
const int keySize = 256; // can be 192 or 128
string ret = Encrypt(plainText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);
return ret;
}
catch (Exception execp)
{
MessageBox.Show(string.Format("Exception in ProtectPassword function\r\nError: {0}", execp.Message));
return "";
}
}
public static string UnprotectPassword(string cipherText)
{
try
{
const string passPhrase = "Ydfv324232r!23%47%7^&ex>,1"; // can be any string
const string saltValue = "s@1tValue"; // can be any string
const string hashAlgorithm = "SHA1"; // can be "MD5"
const int passwordIterations = 101; // can be any number
const string initVector = "@1B2vQ94eZF6g7H1"; // must be 16 bytes
const int keySize = 256; // can be 192 or 128
string ret = Decrypt(cipherText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);
return ret;
}
catch (Exception execp)
{
MessageBox.Show(string.Format("Exception in UnprotectPassword function\r\nError: {0}", execp.Message));
return "";
}
}
以下是我已转换为java的内容,但仍未获得相同的加密输入和输出-我只是将“ ProtectPassword”重命名为“ Encrypt”,将“ UnprotectPassword”重命名为“ Decrypt”
import java.io.ByteArrayOutputStream;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class Encryption {
public static String Encrypt(String str)
{
try
{
String passPhrase = "Ydfv324232r!23%47%7^&ex>,1";
String saltValue = "s@1tValue";
int passwordIterations = 101;
int keySize = 256;
String initVector = "@1B2vQ94eZF6g7H1";
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), saltValue.getBytes("UTF-8"), passwordIterations, keySize);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(initVector.getBytes("UTF-8")));
byte[] encryptedText = cipher.doFinal(str.getBytes("UTF-8"));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(encryptedText);
// properly encode the complete cipher text
return DatatypeConverter.printBase64Binary(outputStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String Decrypt(String str)
{
try
{
String passPhrase = "Ydfv324232r!23%47%7^&ex>,1";
String saltValue = "s@1tValue";
int passwordIterations = 101;
int keySize = 256;
String initVector = "@1B2vQ94eZF6g7H1";
byte[] ciphertext = DatatypeConverter.parseBase64Binary(str);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), saltValue.getBytes(), passwordIterations, keySize);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(initVector.getBytes("UTF-8")));
byte[] plaintext = cipher.doFinal(ciphertext);
return new String(plaintext, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
答案 0 :(得分:0)
密文不同,因为C#代码中的PasswordDeriveBytes
和Java代码中的PBKDF2WithHmacSHA1
生成不同的密钥:
PBKDF2WithHmacSHA1
是PBKDF 2 与SHA-1的实现。PasswordDeriveBytes
的实现基于PBKDF 1 ,但增加了一些扩展。除了C#类型的PasswordDeriveBytes
,还有C#类型的Rfc2898DeriveBytes
,它是具有SHA-1的PBKDF2的实现,因此,与PBKDF2WithHmacSHA1
中的对等物Java代码。
如果可能,应在C#代码中使用Rfc2898DeriveBytes
而不是PasswordDeriveBytes
,请参见例如here或here, PBKDF2 部分。然后两个代码返回相同的密文。
据我所知,没有提供者提供C#类型PasswordDeriveBytes
的Java实现。但是,互联网上有功能上相同的Java实现,例如here。如果Java代码使用这样的实现而不是PBKDF2WithHmacSHA1
,则两个代码都返回相同的密文。但是,正如已经提到的,这应该是第二选择。
答案 1 :(得分:0)
下面承诺的是解决方案-再次感谢您的支持
public static class Encryption
{
public static string Encrypt(string text)
{
var thePassword = "%cFRm*F)N9Rq[6#5";
byte[] IV = Encoding.UTF8.GetBytes("7!,V5u]Bu>q>7zY'");
var md5 = new MD5CryptoServiceProvider();
var password = md5.ComputeHash(Encoding.ASCII.GetBytes(thePassword));
var cipher = new RijndaelManaged();
var encryptor = cipher.CreateEncryptor(password, IV);
var buffer = Encoding.ASCII.GetBytes(text);
return Convert.ToBase64String(encryptor.TransformFinalBlock(buffer, 0, buffer.Length));
}
public static string Decrypt(string text)
{
var thePassword = "%cFRm*F)N9Rq[6#5";
byte[] IV = Encoding.UTF8.GetBytes("7!,V5u]Bu>q>7zY'");
var md5 = new MD5CryptoServiceProvider();
var password = md5.ComputeHash(Encoding.ASCII.GetBytes(thePassword));
var cipher = new RijndaelManaged();
var decryptor = cipher.CreateDecryptor(password, IV);
byte[] input = Convert.FromBase64String(text);
var newClearData = decryptor.TransformFinalBlock(input, 0, input.Length);
return Encoding.ASCII.GetString(newClearData);
}
}
与Java等效
public class Encryption {
public static String Encrypt(String str)
{
try
{
String thePassword = "%cFRm*F)N9Rq[6#5";
byte[] encryptedData;
byte[] IV = "7!,V5u]Bu>q>7zY'".getBytes();
MessageDigest digest = MessageDigest.getInstance("MD5");
SecretKeySpec password = new SecretKeySpec(digest.digest(thePassword.getBytes()), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec IVParamSpec = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, password, IVParamSpec);
encryptedData = cipher.doFinal(str.getBytes());
return DatatypeConverter.printBase64Binary(encryptedData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String Decrypt(String str)
{
try
{
String thePassword = "%cFRm*F)N9Rq[6#5";
byte[] encryptedData = DatatypeConverter.parseBase64Binary(str);
byte[] IV = "7!,V5u]Bu>q>7zY'".getBytes();
MessageDigest digest = MessageDigest.getInstance("MD5");
SecretKeySpec password = new SecretKeySpec(digest.digest(thePassword.getBytes()), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec IVParamSpec = new IvParameterSpec(IV);
cipher.init(Cipher.DECRYPT_MODE, password, IVParamSpec);
byte[] decryptedVal = cipher.doFinal(encryptedData);
return new String(decryptedVal);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}