2015-05-17 5 views
2

Я интегрирую приложение .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 ==

Любая помощь по этому вопросу очень ценится, как я в настоящее время из идей.

+0

Как вы назвали функцию шифрования .NET? Каков алгоритм и размер ключа? –

+0

@ EledraNguyen Я не вызывал функцию .Net. Мне дали код .Net, говорящий, что это то, что они используют на стороне .Net. Но мне нужно отправить значения шифрования из моего Java-компонента. Алгоритм - это AES, используемый с .Net, как подтверждено. – dinukadev

+1

Проблема в том, что функция шифрования в .NET не указывает длину ключа. Скажем, я так называю: SymmetricEncrypt («test», «test»), это означает, что я использую AES 256, CBC, а не 128, как в вашем Java-коде. Кроме того, поскольку они используют PasswordDeriveBytes, вы должны прочитать следующее: http://stackoverflow.com/questions/9231754/c-sharp-passwordderivebytes-confusion. Я хотел бы попробовать и помочь, но не могу без специального вызова в .NET –

ответ

1

Спасибо всем за ценные комментарии. Я попросил авторов модуля .Net изменить их реализацию для использования RFC2898DeriveBytes

Смежные вопросы