2017-03-02 7 views
0

私のバックエンドサーバーは.NETに基づいています。 は、サーバー上で使用Rfc2898DeriveBytes暗号化Rfc2898DeriveBytes for java?

は、これは私が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; 
    } 

のコードでもあります。これはコードです

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のデフォルト反復回数は1024ではなく1000(the source)です。

PBEKeySpecの値がバイトまたはビットであるかどうかわかりませんが、ビット数がJavaの場合は128、C#の場合は256(32バイト)です。

実際、C#で384ビットを求めています。最初の256があなたの暗号鍵になるので、次の128があなたのIVになります(あなたはJavaでランダムに生成されるように見えます)。

384ビットを要求し、getEncoded()を呼び出し、32バイトのキーと16バイトのIVに分割し、そこから処理する必要があります。

+0

Javaコード。 – WISHY