2012-05-12 103 views
1

我一直在嘗試多天來嘗試解決這個問題。RAILO CFML DESede(3DES)加密

第三方web服務要求我與歐洲央行 和PKCS7padding發送使用3DES加密的數據 - 他們使用.NET

railo CFML中的加密功能僅限於DESede沒有任何進一步的選項(即默認值用於密碼模式和填充)。

有沒有人在Railo中遇到過這個問題,並提出了一個解決方案(也許是基於java的)? - 我在這裏認真地拉我的頭髮!

基於Leigh的建議,下面我做了一些改變:

我做了一點點進步,我覺得這個鍵有某種MD5散列的就可以了。

我撈各地的網絡,並修改您的解決方案了一下 - 我不認爲填充是必要的,但在第一次得到的加密字符串似乎是我應該期待什麼,但再仔細的檢查是不正確的:

IvParameterSpec = createObject("java", "javax.crypto.spec.IvParameterSpec"); 
Cipher = createObject("java", "javax.crypto.Cipher"); 
SecretKeySpec = createObject("java", "javax.crypto.spec.SecretKeySpec"); 
BASE64Decoder = createObject("java", "sun.misc.BASE64Decoder"); 
Str = createObject("java", "java.lang.String"); 
MessageDigest = createObject("java", "java.security.MessageDigest"); 

input = "<xml><PanNumber>6280390027626871</PanNumber><Req_Currency_Code>826</Req_Currency_Code><Card_Pin>1234</Card_Pin><Till_Amount></Till_Amount><Auth_Code></Auth_Code></xml>"; 
key = "06098140901984F95E139F29B479D952CB6545C177D21456"; 

md = MessageDigest.getInstance("MD5"); 
md.update(key.getBytes("UTF-8"), 0, key.length()); 
keyBytes = md.digest(); 
newKey = tobase64(keyBytes); 
keyBytes2 = binaryDecode(newKey, "base64"); 
keyBytes2 = arrayMerge(keyBytes, arraySlice(keyBytes, 1, 8)); 
allnewKey = binaryEncode(javacast("byte[]", keyBytes2), "base64"); 

encrypted = encrypt(input, allnewKey, "desede", "base64"); 
WriteDump("encrypted (CF): "& encrypted);` 

結果是:26sfwv2DHDj7EHYd5Qao8veDtPbKIcv8rDVhbLPDEaWHO27EUGRF6KrdbXe7NBUVADYMdGuagfO4Tev584dUcgKGJ2h6kWPZxooNUGMgL2xB7e00YOkLosA8wFD569sZUd1MGKuF9yCjY1zCsAE4SgohkcuK9YZ7BizQma99/W9yOsIjAfHtAqGiep4tMTQ + eFASYtPybccsgi8H4brIB/HAu0kaDSAw

預期resul t是: 26sfwv2DHDj7EHYd5Qao8veDtPbKIcv8rDVhbLPDEaWHO27EUGRF6MxaAzUpJDqQBq8NGgdqmtn6q/wVQNHGWrOE8 + aetKVC78nszS3ZO8AHjwoT1igv4lGl78n8jCHHU + KwnBT7KfXIYMTCuwO/MohIiFbGyhMXPsvv3/G4OY1C2nEkN0LweLh4mTgtU8syT1M9XdmvwhaltsmPoFtoE9FujvQpJCY3

+0

(編輯),你可以發佈一個樣本鍵和結果你正在使用Railo和.net?我認爲Railo只是使用java默認值,它們是'ECB'和'PKCS5Padding'(主要與8字節的PKCS7padding兼容)。所以從理論上講,它應該是開箱即用的。 – Leigh

回答

4

railo CFML內的加密功能被限制爲不DESede任何 進一步的選項(即默認值用於密碼模式,填充爲 )。

是的,我相信它使用java的默認值,即DESede/ECB/PKCS5Padding它們與.NET中的TripleDES/ECB/PKCS7padding兼容。所以只要您使用24字節的密鑰,它應該可以直接使用。

不知道更多,我猜測它可能是您的密鑰大小的問題。 .NET支持16和24字節密鑰,但java只支持24字節密鑰。所以如果你的密鑰只有16個字節,你需要用前8個字節來填充它,以便Java/Railo可以接受。

CF/Railo代碼

<cfscript> 
    input = "DESede (3DES) Encryption in RAILO CFML"; 
    key = "ru8femXhTm9jwdGdhb/4Sw=="; 

    // pad the key with the first eight bytes. then convert back to base64 
    keyBytes = binaryDecode(key, "base64"); 
    keyBytes = arrayMerge(keyBytes, arraySlice(keyBytes, 1, 8)); 
    newKey = binaryEncode(javacast("byte[]", keyBytes), "base64"); 

    encrypted = encrypt(input, newKey, "desede", "base64"); 
    WriteDump("encrypted (CF): "& encrypted); 
</cfscript> 

C#代碼

byte[] input = Encoding.UTF8.GetBytes("DESede (3DES) Encryption in RAILO CFML"); 
byte[] key = Convert.FromBase64String("ru8femXhTm9jwdGdhb/4Sw=="); 

TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider(); 
algorithm.Mode = CipherMode.ECB; 
algorithm.BlockSize = 64; 
algorithm.KeySize = 128; // 16 byte key 
algorithm.Key = key; 
ICryptoTransform cipher = algorithm.CreateEncryptor(); 
byte[] encrypted = cipher.TransformFinalBlock(input, 0, input.Length); 
Console.WriteLine("encrypted (.NET): {0}", Convert.ToBase64String(encrypted)); 

結果:

encrypted (CF): fMPlk0ZqHDwp2zzZs/Cng7Y6r8Acr55UPJYWJTruEesxkBApsEFo6w== 
encrypted (.NET): fMPlk0ZqHDwp2zzZs/Cng7Y6r8Acr55UPJYWJTruEesxkBApsEFo6w== 

更新:奇怪。當我MD5哈希在.NET中的關鍵,我得到你的第一個結果,而不是「預期的結果」

String rawInput = "<xml><PanNumber>6280390027626871</PanNumber><Req_Currency_Code>826</Req_Currency_Code><Card_Pin>1234</Card_Pin><Till_Amount></Till_Amount><Auth_Code></Auth_Code></xml>"; 
    String rawKey = "06098140901984F95E139F29B479D952CB6545C177D21456"; 
    byte[] input = Encoding.UTF8.GetBytes(rawInput); 
    byte[] key = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(rawKey)); 
    // ... rest of code 

結果:

encrypted (.NET): 26sfwv2DHDj7EHYd5Qao8veDtPbKIcv8rDVhbLPDEaWHO27EUGRF6KrdbXe7NB 
UVADYMdGuagfO4Tev584dUcgKGJ2h6kWPZxooNUGMgL2xB7e00YOkLosA8wFD569sZUd1MGKuF9yCjY1 
zCsAE4SgohkcuK9YZ7BizQma99/W9yOsIjAfHtAqGiep4tMTQ+eFASYtPybccsgi8H4brIB/HAu0kaDS 
Aw   
+0

Thanks Leigh - 我發送的測試密鑰是這樣的,如果這有幫助的話,我認爲它的意思是24字節:06098140901984F95E139F29B479D952CB6545C177D21456 – eggwater

+0

並且我可以從中得到一個結果的唯一方法(雖然不符合C#結果)是如果我使用以下函數轉換密鑰: **'newKey = toBase64(binarydecode(「06098140901984F95E139F29B479D952CB6545C177D21456」,「hex」))** ** – eggwater

+0

我已經取得了一些進展,我認爲這是鍵有一些MD5散列在它上面。 – eggwater