需要 Java 这个 C# 加密代码的等价物
Need Java Equivalent of this C# Encryption code
我有以下 C# 代码,但在 Java 中需要完全相同的算法。 c#代码质量好不好,我无能为力。我只关心 Java 编码的字符串是否等效。
//Run GetToken to get encrypted string
var token = GetToken(AMessage, account_name, api_key);
private static byte[] GetBytes(string value, byte[] salt, int length)
{
var deriveBytes = new Rfc2898DeriveBytes(value, salt);
return deriveBytes.GetBytes(length);
}
private static string GetToken(string session, string accountName, string apiKey)
{
byte[] encrypted;
using (AesManaged aes = new AesManaged())
{
var salt = Encoding.Default.GetBytes(apiKey);
var key = GetBytes(accountName, salt, aes.KeySize / 8);
var vector = GetBytes(accountName, salt, aes.BlockSize / 8);
aes.Key = key;
aes.IV = vector;
var memoryStream = new MemoryStream();
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var writer = new StreamWriter(cryptoStream))
{
writer.Write(session);
}
}
}
encrypted = memoryStream.ToArray();
}
return Convert.ToBase64String(encrypted);
}
在朋友的帮助下,我拼凑出了答案。我认为这会对 post 答案有所帮助,这样寻找的人会发现更多未解决的问题。我知道那里有很多加密问题,可能不推荐使用上面的 c# 加密方法。希望这个 c# 到 java 的转换对某人有所帮助。以下是上述 c# 代码问题的 java 代码答案。
尽情享受吧。
private static String Encrypt(String DecryptedText, String accountName, String apiKey) {
byte[] EncryptedStr = {};
if (accountName.length() < 5 || apiKey.length() < 5) {
System.out.println("Name too short");
return DatatypeConverter.printBase64Binary(EncryptedStr);
}
try {
byte[] salt = apiKey.getBytes();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec KeySpec = new PBEKeySpec(accountName.toCharArray(), salt, 1000, 256);
SecretKey key = factory.generateSecret(KeySpec);
KeySpec VectorSpec = new PBEKeySpec(accountName.toCharArray(), salt, 1000, 128);
SecretKey vector = (SecretKey) factory.generateSecret(VectorSpec);
SecretKey secretKey = new SecretKeySpec(key.getEncoded(), "AES");
byte[] ivKeyBytes = vector.getEncoded();
byte[] iv = new byte[16]; // Get IV bytes from the
for (int i = 0; i < iv.length; ++i)
iv[i] = ivKeyBytes[i];
IvParameterSpec ivParm = new IvParameterSpec(iv);
Log("Salt:", false);
Log(salt, true);
Log("Key:", false);
Log(secretKey.getEncoded(), true);
Log("Vector:", false);
Log(iv, true);
// IN C# they are using KeySize=256, Mode=CBC, Padding=PKCS7,
// PKCS7 padding doesn't exist in java so use PKCS5 and hope it works correctly.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// NOTE: Added ivParam to initialize the IV parameter, w/o the first block is off.
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParm);
EncryptedStr = cipher.doFinal(DecryptedText.getBytes("UTF-8"));
} catch (Exception e) {
System.out.println("Exc:" + e.getMessage());
e.printStackTrace(System.out);
}
return DatatypeConverter.printBase64Binary(EncryptedStr);
}
}
我有以下 C# 代码,但在 Java 中需要完全相同的算法。 c#代码质量好不好,我无能为力。我只关心 Java 编码的字符串是否等效。
//Run GetToken to get encrypted string
var token = GetToken(AMessage, account_name, api_key);
private static byte[] GetBytes(string value, byte[] salt, int length)
{
var deriveBytes = new Rfc2898DeriveBytes(value, salt);
return deriveBytes.GetBytes(length);
}
private static string GetToken(string session, string accountName, string apiKey)
{
byte[] encrypted;
using (AesManaged aes = new AesManaged())
{
var salt = Encoding.Default.GetBytes(apiKey);
var key = GetBytes(accountName, salt, aes.KeySize / 8);
var vector = GetBytes(accountName, salt, aes.BlockSize / 8);
aes.Key = key;
aes.IV = vector;
var memoryStream = new MemoryStream();
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var writer = new StreamWriter(cryptoStream))
{
writer.Write(session);
}
}
}
encrypted = memoryStream.ToArray();
}
return Convert.ToBase64String(encrypted);
}
在朋友的帮助下,我拼凑出了答案。我认为这会对 post 答案有所帮助,这样寻找的人会发现更多未解决的问题。我知道那里有很多加密问题,可能不推荐使用上面的 c# 加密方法。希望这个 c# 到 java 的转换对某人有所帮助。以下是上述 c# 代码问题的 java 代码答案。
尽情享受吧。
private static String Encrypt(String DecryptedText, String accountName, String apiKey) {
byte[] EncryptedStr = {};
if (accountName.length() < 5 || apiKey.length() < 5) {
System.out.println("Name too short");
return DatatypeConverter.printBase64Binary(EncryptedStr);
}
try {
byte[] salt = apiKey.getBytes();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec KeySpec = new PBEKeySpec(accountName.toCharArray(), salt, 1000, 256);
SecretKey key = factory.generateSecret(KeySpec);
KeySpec VectorSpec = new PBEKeySpec(accountName.toCharArray(), salt, 1000, 128);
SecretKey vector = (SecretKey) factory.generateSecret(VectorSpec);
SecretKey secretKey = new SecretKeySpec(key.getEncoded(), "AES");
byte[] ivKeyBytes = vector.getEncoded();
byte[] iv = new byte[16]; // Get IV bytes from the
for (int i = 0; i < iv.length; ++i)
iv[i] = ivKeyBytes[i];
IvParameterSpec ivParm = new IvParameterSpec(iv);
Log("Salt:", false);
Log(salt, true);
Log("Key:", false);
Log(secretKey.getEncoded(), true);
Log("Vector:", false);
Log(iv, true);
// IN C# they are using KeySize=256, Mode=CBC, Padding=PKCS7,
// PKCS7 padding doesn't exist in java so use PKCS5 and hope it works correctly.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// NOTE: Added ivParam to initialize the IV parameter, w/o the first block is off.
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParm);
EncryptedStr = cipher.doFinal(DecryptedText.getBytes("UTF-8"));
} catch (Exception e) {
System.out.println("Exc:" + e.getMessage());
e.printStackTrace(System.out);
}
return DatatypeConverter.printBase64Binary(EncryptedStr);
}
}