2013-05-17 321 views
6

Dịch vụ Đăng nhập Im lặng được viết bằng Coldfusion9 chấp nhận các chuỗi được mã hóa từ các hệ thống bên ngoài và sau đó giải mã dựa trên thiết lập Thuật toán/Mã hóa đã được đồng ý. Điều này đã làm việc mà không có vấn đề trong nhiều năm nay từ các hệ thống chạy ASP/JAVA/PHP, nhưng bây giờ chúng ta có một khách hàng không có lựa chọn nào khác ngoài sử dụng CryptoJS để thực hiện mã hóa và cho cuộc sống của tôi. giải mã trong Coldfusion.Mã hóa AES trong CryptoJS và giải mã trong Coldfusion

Kiến thức về mã hóa của tôi không phải là điều tuyệt vời nhưng điều tôi nhận thấy là mật mã được mã hóa của CryptoJS cho cùng một chuỗi/khóa giống nhau mỗi khi tôi thực hiện mã hóa trong khi Coldfusion/Java i luôn có thể được mã hóa chính xác chuỗi. Tôi không chắc liệu đây có phải là mã hóa có liên quan hay không nhưng tôi chưa bao giờ gặp vấn đề này khi chấp nhận chuỗi mã hóa từ bất kỳ hệ thống nào khác trước đây, vì vậy tôi hy vọng đó là cách tôi mã hóa trong CryptoJS không chính xác.

<cfoutput> 

<!--- Set String and Key ---> 
<cfset theKey = toBase64("1234567812345678")> 
<cfset string = "[email protected]"> 

<!--- CryptoJS AES Libraries ---> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script> 

<script> 

// Encrypt String using CryptoJS AES 
var encrypted = CryptoJS.AES.encrypt("#string#", "#theKey#"); 
console.log(encrypted.toString()); 

// Decrypt String using CryptoJS AES 
var decrypted = CryptoJS.AES.decrypt(encrypted, "#theKey#"); 
console.log(decrypted.toString(CryptoJS.enc.Utf8)); 

</script> 

<!--- Coldfusion Decrypt String/FAILS ---> 
Decrypted: #decrypt(encryptedEmail, "#theKey#", "AES", "BASE64")# 

</cfoutput> 
+0

mã mẫu của bạn không chạy vì bạn có thể ' kết hợp các biến JavaScript và ColdFusion với nhau như bạn. JavaScript là phía máy khách và ColdFusion là phía máy chủ, họ không thể nói cách bạn đang cố gắng làm cho chúng hoạt động. –

+0

Matt khi tập lệnh này đang được chạy dưới dạng CFM và được phân tích/biên soạn bởi Coldfusion thì các biến này sẽ được đánh giá trước khi javascript được chạy. Tôi đã làm việc trên rất nhiều dự án trong những năm mà coldfusion và javascript đang trao đổi dữ liệu, tôi nghĩ vấn đề ở đây liên quan đến việc mã hóa trong CryptoJS và tôi tiếp cận điều này từ một góc đơn giản. –

+0

Email được mã hóa không được xác định ở bất kỳ đâu. Đó không phải là vấn đề tổng thể của bạn, nhưng mã mẫu không đưa ra lỗi bạn nói nó –

Trả lời

11

Dường như có hai vấn đề:

  1. CryptoJS không sử dụng biến của bạn như key. Như @ Miguel-F đã đề cập, khi bạn chuyển một chuỗi, "it's treated as a passphrase and used to derive [the] actual key and IV". Cả hai được tạo ngẫu nhiên, đó là lý do tại sao kết quả được mã hóa của bạn tiếp tục thay đổi. Nhưng quan trọng hơn, điều này có nghĩa là CryptoJS đang sử dụng key hoàn toàn khác với mã trong mã CF của bạn và đó là lý do tại sao giải mã() không thành công. (Ít nhất nó là một phần của lý do ...)

  2. Vấn đề thứ hai là ngoài thuật toán "AES", còn có hai cài đặt mã hóa khác phải khớp với: modepadding scheme. Mặc dù CryptoJS và ColdFusion sử dụng cùng các mặc định cho sơ đồ đệm, các "chế độ" khác nhau:

Bạn cần phải đảm bảo tất cả ba thiết lập đều giống nhau ở cả hai bên. Hãy thử sử dụng chế độ CBC trong CF, vì nó an toàn hơn ECB. Lưu ý: Yêu cầu thêm giá trị IV.

Mã CF:

<!--- this is the base64 encrypted value from CryptoJS ---> 
<cfset encrypted = "J2f66oiDpZkFlQu26BDKL6ZwgNwN7T3ixst4JtMyNIY="> 
<cfset rawString = "[email protected]"> 
<cfset base64Key = "MTIzNDU2NzgxMjM0NTY3OA=="> 
<cfset base64IV = "EBESExQVFhcYGRobHB0eHw=="> 

<cfset ivBytes = binaryDecode(base64IV, "base64")> 
<cfoutput> 
    #decrypt(encrypted, base64Key, "AES/CBC/PKCS5Padding", "base64", ivBytes)# 
</cfoutput> 

CryptoJS: (Adjusted gốc Ví dụ)

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script> 
<script> 
    var text = "#rawString#"; 
    var key = CryptoJS.enc.Base64.parse("#base64Key#"); 
    var iv = CryptoJS.enc.Base64.parse("#base64IV#"); 

    var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv}); 
    console.log(encrypted.toString()); 

    var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv}); 
    console.log(decrypted.toString(CryptoJS.enc.Utf8)); 
</script> 


Edit:

Tất cả những gì đã nói, ý của bạn là gì bởi khách hàng "không có lựa chọn nào khác ngoài việc sử dụng CryptoJS để thực hiện mã hóa"? Tại sao họ không thể sử dụng mã hóa phía máy chủ?Tôi không phải là chuyên gia mã hóa, nhưng thực hiện mã hóa bằng javascript và để lộ khóa trên máy khách, không âm thanh cực kỳ an toàn để bắt đầu ...

+0

+1 @Leigh - Tôi đã nhìn vào nó sáng nay (nhưng sau đó đã phải rời khỏi) và về cơ bản đến cùng một kết luận như bạn. Nếu không có tất cả các phần, Coldfusion sẽ không thể giải mã được giá trị. Tôi thậm chí đã viết lên một kịch bản thử nghiệm tương tự như những gì bạn có ở đây nhưng không bao giờ làm cho nó giải mã chính xác ... –

+0

Vâng, nó thường là một cái gì đó nhỏ như một sự khác biệt như mã hóa, chế độ hoặc padding. Nhưng với mã hóa đó là tất cả nó cần để có được một kết quả hoàn toàn khác nhau ;-) @Phil - Vì lợi ích của rõ ràng, bạn có thể muốn đặt chế độ CryptoJS và padding rõ ràng là '{iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7} '. Chỉ cần như vậy là rõ ràng. – Leigh

+0

@ Miguel-F - Đối với grins tôi đã thử sử dụng chế độ 'ECB' kém an toàn hơn. Nhưng không có may mắn với nó. Các tài liệu nói rằng nó được hỗ trợ, nhưng tôi không chắc chắn .. bởi vì họ cũng nói * "Nếu bạn vượt qua khóa thực tế, bạn cũng phải vượt qua IV thực tế." *. Vì ECB không sử dụng một 'iv' không có ý nghĩa .. Mặc dù vậy, dù sao CBC cũng tốt hơn. – Leigh