5

私はすでにRSA経由でランダムな対称鍵を共有することができました. ただし、aes-encryption を使用することはできません。問題は、cryptoJS が使用するソルトと初期化ベクトルにあるようです。

まず、出力は次のようになります。

U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc 

悲しいことに、繰り返し発生する「U2FsdGVkX」または「cryptoJS.AES出力」のグーグルは役に立ちません。

一方、golang の aes では、32 ビット キーとそれぞれ 32 ビット長の入力のみが必要です。つまり、何らかの方法で上記を対応するブロックに分割し、秘密鍵と上記のデータ (おそらくソルト + 初期ベクトルを含む) から 32 ビット キーを作成する方法を見つけ出す必要があります。

悲しいことに、 http://code.google.com/p/crypto-jsも Google 検索も解決策を提供してくれません。

ちなみに、今の私の暗号化:

var arr = new Array(32);
symetricKey = "";
var symHex = "";
rng.nextBytes(arr);
for(var i = 0; i < arr.length; i++){
    symetricKey += String.fromCharCode(arr[i]);
    //symHex= arr[i].toString(16), added a 0 if needed (so length always increases by 2)
}
//submit symetric via rsa. This is working, the server gets that key
var enc = CryptoJS.AES.encrypt(unencrypted, symetricKey)
//submit enc, stuck now - what to do with it on the server?


編集: Base64 応答の後:
base64 の入力に感謝します。
しかし、私はまだそれを機能させることができません。
特に、エンコードされた文字列が「SALTED」で始まるため、問題がある可能性があると思います。

今エンコードしようとしている方法:
クライアントでエンコード:

var unencrypted = "{mail:test,password:test}"
var enc = CryptoJS.AES.encrypt(unencrypted, symKey)

サーバーでは、変数 enc と symKey はクライアントと同じです。

baseReader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(enc))
encData, err := ioutil.ReadAll(baseReader)
//if err != nil { ....}, doesn't happen here
cipher, err := aes.NewCipher(symKey)
//if err != nil { ....}, doesn't happen here
byteData := make([]byte, len(encData))
cipher.Decrypt(byteData, encData)
fmt.Println("Dec: ", string(byteData))
//Outputs unrepresentable characters

何か案が?

4

4 に答える 4

7

CryptoJS.AES.encrypt の出力は、キー、IV、オプションのソルト、および暗号文を含む CipherParams オブジェクトです。参照していた文字列は、OpenSSL 互換のフォーマットされた文字列でした。

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");

alert(encrypted.key);        // 74eb593087a982e2a6f5dded54ecd96d1fd0f3d44a58728cdcd40c55227522223
alert(encrypted.iv);         // 7781157e2629b094f0e3dd48c4d786115
alert(encrypted.salt);       // 7a25f9132ec6a8b34
alert(encrypted.ciphertext); // 73e54154a15d1beeb509d9e12f1e462a0

alert(encrypted);            // U2FsdGVkX1+iX5Ey7GqLND5UFUoV0b7rUJ2eEvHkYqA= (OpenSSL-compatible format strategy)

CryptoJS のデフォルトの暗号化モードは CBC です。RSA で暗号化された交換中に、対称キーと共に IV を渡す必要があります。サーバー上の対称キー、IV、および暗号化テキストのバイト配列を使用すると、次のように Go で復号化できます。

c, err := aes.NewCipher(key)
cfbdec := cipher.NewCBCDecrypter(c, iv)
plaintext := make([]byte, len(ciphertext))
cfbdec.CryptBlock(plaintext, ciphertext)
于 2013-01-18T16:59:46.430 に答える
2
U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc 

そのデータはbase64エンコードされ、生のままで次のようになります。

Salted__po5jSgm[!P8=Yacv,dj`

(その文字列には表現できない文字があることに注意してください)

これは正確に 32 バイトの長さです。

于 2013-01-18T15:44:55.123 に答える
1

ただし、直接ではありませんが、https://github.com/dgryski/dkeyczarを見ると役立つ場合があります。

その Go 実装であるKeyCzarは、もともと Google セキュリティ チームのメンバーによって開発されたオープン ソースの暗号化ツールキットです。

このプロジェクトから何かを学んでいただければ幸いです

于 2014-04-14T15:21:39.603 に答える
0

おそらく、解決しなければならない問題がいくつかあります。

まず、encrypt() に正しいタイプの引数を指定していることを確認する必要があります。元の投稿にはまだ反映されていませんが、コメントで CryptoJS.enc.Hex.parse(symetricKeyHex) を実行する必要があることに気付いたようです。

次に、両端で IV を取得または作成する方法を決定する必要があります。パスフレーズを使用する場合、CryptoJS はそれを作成できますが、パスフレーズではなく実際のキーを使用しようとしています。つまり、キーを設定するように IV を設定する必要があります。

最後に、IV と暗号文の両方を送信する方法を決定する必要があります。典型的で簡単な解決策は、IV を暗号文の先頭に追加することですが、実際には、簡単にシリアライズ/アンシリアライズできるものであれば何でも問題なく機能します。決定したフォーマットが両端で一貫していることを確認してください。

于 2013-01-30T04:56:12.277 に答える