2012-02-21 127 views
0

我必须解密一个以C#加密的字符串作为我们项目的一部分。该解密使用AES算法和打包模式作为PKCS7完成。为了生成初始化向量,他们使用了以下内容:RFC2898DeriveBytes在Java中的实现

Rfc2898DeriveBytes keyGenerator = new Rfc2898DeriveBytes("somestring", salt); 

salt是默认字节。

此IV用于使用AES加密字符串。

我已经通读了一些文档,发现AES可以用Java实现。但不知道如何通过IV和包装模式。

此外,我已经看到,有提及密码块模式的模式CBC,ECB。我不确定在C#中使用什么模式。

下面是C#

/// Method to encrypt the plain text based on the key and Iv 
/// </summary> 
/// <param name="plainText"></param> 
/// <param name="key"></param> 
/// <returns>encrypted Text</returns> 
private string Encrypt(string plainText, byte[] key) 
{ 
    if (plainText == null || plainText.Length <= 0) 
     throw new ArgumentNullException("plainText"); 
    if (key == null || key.Length <= 0) 
     throw new ArgumentNullException("Key"); 
    // Declare the stream used to encrypt to an in memory 
    // array of bytes. 
    MemoryStream msEncrypt = null; 

    // Declare the RijndaelManaged object 
    // used to encrypt the data. 
    AesCryptoServiceProvider aesAlg = null; 
    // using (new Tracer("Encryption","","")) 
    // { 
     try 
     { 
      // Create a RijndaelManaged object 
      // with the specified key and IV. 
      aesAlg = new AesCryptoServiceProvider(); 
      aesAlg.Key = key; 
      aesAlg.IV = GetInitializationVector(); 
      aesAlg.Padding = PaddingMode.PKCS7; 
      // Create an encryptor to perform the stream transform. 
      ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 

      // Create the streams used for encryption. 
      msEncrypt = new MemoryStream(); 
      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
      { 
       using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
       { 

        //Write all data to the stream. 
        swEncrypt.Write(plainText); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      // Clear the RijndaelManaged object. 
      if (aesAlg != null) 
       aesAlg.Clear(); 
     } 

     // Return the encrypted bytes from the memory stream. 
     // Console.WriteLine(); 

     return Convert.ToBase64String(msEncrypt.ToArray()); 
    // } 
} 

private byte[] GetInitializationVector() 
{ 
    byte[] iv; 
    //create the initial salt 

    byte[] salt = Encoding.Default.GetBytes("abcdefghijkl"); 

    //create the key generator 

    Rfc2898DeriveBytes keyGenerator = new Rfc2898DeriveBytes("ricksaw", salt); 

    iv = keyGenerator.GetBytes(16); 

    return iv; 
} 

任何一个可以帮助我在Java中创建等价的代码?

+0

'Rfc2898DeriveBytes'基于PBKDF2 – CodesInChaos 2012-02-21 12:03:11

+0

那么有没有在java中的任何类实现PBKDF2 – VamsiKrishna 2012-02-21 12:06:33

+1

@krish - 我不知道。你可以看一下'PBKDF2WithHmacSHA1',在java 6中添加。Re:* C#cipher模式* [默认是cbc](http://msdn.microsoft.com/en-us/library/system.security.cryptography .symmetricalgorithm.mode.aspx)。你还可以发布你的Java代码到目前为止? – Leigh 2012-02-22 03:30:49

回答

0

我不知何故算了一个办法。它正在正常工作

我已经请求.net对应方将密钥和IV作为字符串传递。我将它们编码为字节[],并使用下面的代码

String sKey ="fromdotnetpart"; 

String sIv="fromdotnetiv"; 

    byte[] bKey = key.getBytes(); 
    byte[] iv = sIv.getBytes(); 
    SecretKeySpec skey = new SecretKeySpec(bKey, "AES"); 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    AlgorithmParameterSpec param = new IvParameterSpec(iv); 
    cipher.init(Cipher.DECRYPT_MODE, key,param); 
    String decrypted = cipher.doFinal(encryptedString.getByte()); 

希望这可以帮助你。请注意,高强度的AES加密即AES-256192等你需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files