2016-08-05 41 views
0

JavascriptとCryptoJSを使用してJavaアプリケーションで使用される暗号化を複製しようとしています。私はCryptoJSがキーの文字列を期待しているように、SecretKeySpecをどのように複製する必要があるのか​​よく分かりません。Java AES CryptoJSを使用したJavascriptの暗号化

public byte[] encrypt(byte[] origin) 
    { 
     String key = "testkey"; 
     SecretKeySpec sks = new SecretKeySpec(convertAESKey(key), "AES"); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     byte[] iv = new byte[16]; 
     cipher.init(Cipher.ENCRYPT_MODE, sks, new IvParameterSpec(iv)); 
     return cipher.doFinal(origin); 
    } 

private byte[] convertAESKey(String key) 
    { 
     byte[] keyBytes; 
     keyBytes = key.getBytes("UTF-8"); 
     byte[] keyBytes16 = new byte[16]; 
     System.arraycopy(keyBytes, 0, keyBytes16, 0, 
       Math.min(keyBytes.length, 16)); 
     return keyBytes16; 
    } 
} 

私のJSコードこれまで:ここ

は、私はJSで複製する必要があるのJavaの暗号化コードである

var iv = new Uint8Array(16); 
var key = "testkey"; 

var encrypted = CryptoJS.AES.encrypt(
    someByteArray, 
    key, 
    { 
     iv: iv, 
     mode: CryptoJS.mode.CBC 
    } 
); 

また、暗号の最終出力は暗号化されたバイト配列であります。 CryptoJSの最終出力は、cipherTextを持つオブジェクトのようです。出力をバイト配列として取得する方法はありますか?

暗号化されたレスポンスを文字列に変換してからバイト配列に変換するだけですが、これはJava暗号化の出力と一致しません。

+0

ボックスからの暗号化を使用しても問題はありません。現在の実装がClient(Java)to Server(Java)であり、Client(Javascript)to Server(Java)にする必要があるため、問題はJava暗号化を複製しています。サーバーコードは変更できないため、暗号化を正確に一致させることが重要です。 – mildse7en

答えて

1

CryptoJSはデフォルトでUint8Arrayを処理しないので、私はそれを使用せず、バイナリデータを表すためにデフォルトのWordArrayを使用します。

var iv = CryptoJS.lib.WordArray.create([0, 0, 0, 0]); 
var key = "testkey"; 

key = CryptoJS.enc.Utf8.parse(key); 
for (var i = key.words.length; i < 4; i++) { 
    key.words[i] = 0; 
} 
key.sigBytes = 16; 
key.clamp(); 

var encrypted = CryptoJS.AES.encrypt(
    someByteArray, 
    key, 
    { 
     iv: iv, 
     mode: CryptoJS.mode.CBC 
    } 
); 
console.log(encrypted.ciphertext.toString(CryptoJS.enc.Hex)); 

これは、Javaで生成された暗号文と簡単に比較できる16進文字列を提供します。


このコードは非常に安全ではありません。

  • IVは予測不可能でなければならない(読み:ランダム)。静的IVを使用しないでください。これは、暗号を決定論的にし、したがって意味的に安全ではないためです。暗号文を観察する攻撃者は、同じメッセージプレフィックスがいつ送信されたかを判断できます。 IVは秘密ではないので、暗号文とともに送ることができます。通常は、単純に暗号文の前に付加され、解読の前にスライスされます。

  • キーはランダムである必要があります(読み取り:ランダムノイズのように見えます)。テキストがランダムに見えず、パスワードをキーとして誤ってセキュリティを低下させます。パスワードをお持ちの場合は、PBKDF2、bcrypt、scrypt、または反復回数/コスト係数が高いArgon2などを使用してキーを派生させる必要があります。

  • (悪意のある)操作を検出するには、暗号テキストを認証する必要があります。これをしないと、パッディング・オラクル攻撃に対して脆弱になる可能性があります。認証は、GCMやEAXなどの認証された操作モード、またはHMAC-SHA256などの強力なMACを使用する暗号化MAC方式を使用して実行できます。

+0

これをお試しいただきありがとうございます。私は "未定義はオブジェクトではありません(評価" e.length ")" – mildse7en

+0

あなたは 'someByteArray'とは何も言わなかったので、私はそれが文字列か 'WordArray'です。 'Uint8Array'の場合、lib-typedarrays.jsファイルをインクルードしてサポートを得ることができます。 –

+0

私はlib-typedarrays.jsファイルをインクルードしようとしましたが、同じエラーが表示されます。配列をエンコードしようとすると、Uint8Array [120,156,203,72,205,201,201,7,0,6,42,2,21]と表示されます – mildse7en

関連する問題