2017-03-02 101 views
0

我的后端服务器基于.NET。 在服务器上有使用Rfc2898DeriveBytes加密Rfc2898DeriveBytes for java?

这是净

的代码
public static string Encrypt(string clearText) 
    { 
     string EncryptionKey = "abc123"; 
     byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); 
     using (Aes encryptor = Aes.Create()) 
     { 
      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
      encryptor.Key = pdb.GetBytes(32); 
      encryptor.IV = pdb.GetBytes(16); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) 
       { 
        cs.Write(clearBytes, 0, clearBytes.Length); 
        cs.Close(); 
       } 
       clearText = Convert.ToBase64String(ms.ToArray()); 
      } 
     } 
     return clearText; 
    } 

我写的客户端JAVA。这是代码

try { 
     String encryptKey = "abc123"; 
     byte[] salt = new byte[]{0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}; 
     SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
     KeySpec spec = new PBEKeySpec(encryptKey.toCharArray(), salt, 1024, 128); 
     SecretKey tmp = factory.generateSecret(spec); 
     SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
     System.out.println("Key:" + Base64.encodeToString(secret.getEncoded(), Base64.DEFAULT)); 


     String cleartext = "12345"; 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, secret); 
     AlgorithmParameters params = cipher.getParameters(); 
     byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); 
     byte[] ciphertext = cipher.doFinal(cleartext.getBytes("UTF-8")); 
     System.out.println("IV:" + Base64.encodeToString(iv, Base64.DEFAULT)); 
     System.out.println("Cipher text:" + Base64.encodeToString(ciphertext, Base64.DEFAULT));; 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidParameterSpecException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 

我在java中得不到与.Net相同的结果。 服务器上的12345的加密值为dAQWIrbtHv/eDbu+4oJD0g==

虽然我得到tcvGLK5r99jt6PFLALpRfQ==

什么是修复我需要申请?

+0

你需要从Java中的PBKDF2中获得IV,但是你总是生成一个随机的IV。 –

+0

@ArtjomB。你可以分享代码吗? – WISHY

+0

如果你写了所有的代码,那么你也可以进行更改?还是你只是复制并粘贴你的安全代码? –

回答

2

Rfc2898DeriveBytes的默认迭代计数为1000,而不是1024(每the source)。

我不知道PBEKeySpeckeyLength值是以字节为单位还是以位为单位,但是如果是在Java中请求128位而在C#中则是256(32字节)。

呃,实际上,你已经要求C#中的384位。因为前256个变成你的密码密钥,那么接下来的128个变成你的IV(你似乎让它在Java中随机生成)。

因此,您可能需要询问384位,请拨getEncoded(),将答案分为32字节密钥和16字节IV,然后从此处继续。

+0

我应该做什么改变Java代码。 – WISHY