Я интегрирую приложение .NET, использующее симметричное шифрование. Мое приложение находится на Java. Ниже приведен код .Net, который был разделен командой, использующей симметричное шифрование;Проблема симметричного шифрования между .Net-приложением и Java-приложением
public static string SymmetricEncrypt<T>(string value, string PrivateKey, string SALT_STRING) where T : SymmetricAlgorithm, new()
{
PasswordDeriveBytes rgb =
new PasswordDeriveBytes(PrivateKey ,
Encoding.Unicode.GetBytes(SALT_STRING));
SymmetricAlgorithm algorithm = new T();
byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);
ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);
using (MemoryStream buffer = new MemoryStream())
{
using (CryptoStream stream =
new CryptoStream(buffer, transform, CryptoStreamMode.Write))
{
using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
{
writer.Write(value);
}
}
return Convert.ToBase64String(buffer.ToArray());
}
}
Глядя на документации .Net, я мог видеть, что класс SymmetricEncrypt по умолчанию использует шифрование Rijndael. А также я нашел класс, похожий на реализацию «PasswordDeriveBytes» в bouncy castle, который реализует алгоритм «PKCS5S1» для генерации ключей с использованием соли с числом итераций 100. Но все же я не могу сгенерировать точное шифрование до требуемого с помощью приложения .Net. Следующий код - это то, что я пробовал до сих пор;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import mtnsa.sorb.handler.PKCS5Test.PasswordDeriveBytes;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Base64;
public class EncryptionHelper {
public static void main(String[] args)throws Exception {
encrypt("FTTH","HhN01vcEEtMmwdNFliM8QYg0Y89xzBOJJG7BHARC7g", "002400000480000094000000060200000024000052534131000400000100010085525e9438e9fae122f71ec7124" +
"443bf2f9f57f5f3760b3704df168493004b9ef68413f500d54fa9fa3869b42b1e2365204826e54b618d56e7e575f2" +
"7f675f0eae3ea8458a8ee1e92dc3f4bfc34fbe23851afa9d2c28fc8cd5b124f60a03a06bfb598bc3acbd8c4380ae" +
"f02cc58bdf955d140390f740a7e115c59e3b3b5758ca");
}
public static String encrypt(final String valueToEncrpt, final String saltString, final String privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{
String encrptedValue = null;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] password = privateKey.getBytes();
byte[] salt = saltString.getBytes();
PKCS5S1ParametersGenerator generator = new PasswordDeriveBytes(new SHA1Digest());
generator.init(password, salt, 100);
byte[] keyArr = ((KeyParameter)generator.generateDerivedParameters(128)).getKey();
byte[] IvArr = ((KeyParameter)generator.generateDerivedParameters(128)).getKey();
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyArr,"AES"),new IvParameterSpec(IvArr));
byte[]test = cipher.doFinal(valueToEncrpt.getBytes());
System.out.println(new String(Base64.encode(test)));
return encrptedValue;
}
}
В коде Java я дал образец ключа SALT и ключ PRIVATE, используемый для целей тестирования. Но все же я не могу получить точное значение, созданное приложением .Net. Ниже приведен пример простого текста и зашифрованного значения, которое я получил из приложения .Net, которое не удалось выполнить в моем Java-коде.
Обычный текст Значение: FTTH
зашифрованное значение: MjgmbdT3Vg6RW/7K1BjQ/Q ==
Любая помощь по этому вопросу очень ценится, как я в настоящее время из идей.
Как вы назвали функцию шифрования .NET? Каков алгоритм и размер ключа? –
@ EledraNguyen Я не вызывал функцию .Net. Мне дали код .Net, говорящий, что это то, что они используют на стороне .Net. Но мне нужно отправить значения шифрования из моего Java-компонента. Алгоритм - это AES, используемый с .Net, как подтверждено. – dinukadev
Проблема в том, что функция шифрования в .NET не указывает длину ключа. Скажем, я так называю: SymmetricEncrypt («test», «test»), это означает, что я использую AES 256, CBC, а не 128, как в вашем Java-коде. Кроме того, поскольку они используют PasswordDeriveBytes, вы должны прочитать следующее: http://stackoverflow.com/questions/9231754/c-sharp-passwordderivebytes-confusion. Я хотел бы попробовать и помочь, но не могу без специального вызова в .NET –