2013-01-18 111 views
3

我已經設法通過rsa共享隨機對稱密鑰。 但是我無法使用aes加密工作。 問題似乎是cryptoJS使用的鹽和初始化向量。CryptoJS.AES和Golang

首先,它的輸出線沿線的:

U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc 

谷歌搜索的reoccuring「U2FsdGVkX」或「cryptoJS.AES輸出」可悲的是就是沒有用的。

另一方面,golang的aes只需要一個32位密鑰和每個32位長度的輸入。 這意味着我必須以某種方式將上面的代碼拆分成相應的塊,並找出如何從祕密密鑰和上面的數據(可能包含salt + init向量)中創建32位密鑰。

不幸的是既不http://code.google.com/p/crypto-js也沒有任何谷歌搜索提供了一個解決方案。

順便說一句 - 我的加密現在:

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 

任何想法?

回答

3

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,並在服務器上的密文字節數組,你可以轉到與此類似解密:

c, err := aes.NewCipher(key) 
cfbdec := cipher.NewCBCDecrypter(c, iv) 
plaintext := make([]byte, len(ciphertext)) 
cfbdec.CryptBlock(plaintext, ciphertext) 
+0

我發誓我越來越絕望。 Plain:「Test Message」,SymKey:\t「7a27aae91016ac602fe09f0eb0223c91」,cipher:\t 22d7f22417a477ad11cd2bb4ec158f61,IV:6a9497796914c5bd835d9b5264934ad0,Decode:4N ?? k?\ 0 ???&1?K?W?N ?? 請注意,symkey是一個字符串,在這裏不是hex。 我試着把密碼+ iv當作字符串以及十六進制來處理,無濟於事。 – user1977711

+0

缺少的是以下內容:您必須symetricKey = CryptoJS.enc.Hex.parse(symetricKeyHex);併發送enc.ciphertext.toString()。substr(0,64);不管剩下的字節是什麼,我不知道,我找不到IV。 – user1977711

2
U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc 

該數據被base64編碼,生它看起來是這樣的:

Salted__po5jSgm[!P8=Yacv,dj` 

(注意,在該字符串不可表示的字符)

而這正是32個字節長。

+0

嗨學東西的成員開發,開源加密工具庫可悲的是,我仍然不能使它工作。我在第一篇文章中編輯了更多細節。 Stackoverflow不會讓我把它發佈在答案中,並且評論太長了。 – user1977711

+0

base64編碼的字符串是OpenSSL兼容的格式策略。 CryptoJS文檔描述了不同的格式策略,並允許您選擇一種。通過執行enc.toString()(這基本上就是您的代碼所做的),它將返回默認策略。 CipherParams(通過加密返回的對象)上的屬性包含密鑰,密文,IV和鹽的字節數組。 – Bort

0

有可能我們需要通過工作的幾個問題。

首先,您需要確保提供正確類型的參數給encrypt()。看起來您可能已經意識到您需要執行CryptoJS.enc.Hex.parse(symetricKeyHex),儘管您的原始文章尚未反映此內容。

其次,您需要決定如何在兩端獲得或創建IV。如果您使用密碼短語,CryptoJS可以創建一個,但您試圖使用實際的密鑰而不是密碼短語。這意味着您必須像設置密鑰一樣設置IV。

最後,你必須決定如何傳輸IV和密文。一個典型和簡單的解決方案是將IV預先加密到密文,但是真正可以輕鬆進行序列化/非序列化的任何東西都可以正常工作。只要確保你決定的任何格式在兩端都是一致的。