解密ColdFusion中的字符串在C#中使用3DES加密 [英] Decrypting a string in ColdFusion encrypted with 3DES in C#

查看:181
本文介绍了解密ColdFusion中的字符串在C#中使用3DES加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们遇到了困难解密ColdFusion中的字符串是$ P $与3DES和C#pviously加密。这是我们最初用来加密字符串code:

 公共静态字符串EncryptTripleDES(明文字符串,字符串键)
    {
    TripleDESCryptoServiceProvider DES =新TripleDESCryptoServiceProvider();
    MD5CryptoServiceProvider hashMD5 =新MD5CryptoServiceProvider();
    DES.Key = hashMD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(键));
    DES.Mode = CipherMode.ECB;
    ICryptoTransform的DESEncrypt = DES.CreateEncryptor();
    字节[]缓冲区= ASCIIEncoding.ASCII.GetBytes(明文);    串EncString = Convert.ToBase64String(DESEncrypt.TransformFinalBlock(缓冲液,0,Buffer.Length));
    EncString = EncString.Replace(+,@@ 12);    返回EncString;
    }

我们在这里使用建议尝试:

<一个href=\"http://stackoverflow.com/questions/1474801/tripledes-encryption-net-and-coldfusion-not-playing-nice\">TripleDES加密 - .NET和ColdFusion打不出漂亮的

..没有运气。这里是我们的CF code和错误:

 &LT; CFSET variables.theKey =blahblah/&GT;
  &LT; CFSET variables.theAlgorithm =的DESede / CBC / PKCS5Padding&GT;
  &LT; CFSET variables.theEncoding =Base64编码&GT;
  &LT; CFSET strTest =解密(#DB.PASSWORD#,variables.theKey,variables.theAlgorithm,variables.theEncoding)GT;

返回错误:试图加密或解密您的输入字符串时出现错误:'无法去code字符串blahblah

所以,它看起来像它试图解密密钥,而不是字符串,但这是解密功能并不怎么ColdFusion的概述。任何想法?

更新:已尝试使用以下CF code,但返回的错误仍然是试图加密或解密您的输入字符串时出错:由于最后一块未正确填充。

 &LT; CFSET DBPASSWORD =Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL&GT;
&LT; CFSET finalText =替换(DBPASSWORD,@@ 12,+,全)&GT;
&LT; CFSET theKey =ABCDEFGH&GT;
&LT; CFSET theKeyInBase64 = toBase64(theKey)GT;
&LT; CFSET hashedKey =散列(theKeyInBase64,MD5)&GT;
&LT; CFSET padBytes =左(hashedKey,16)&GT;
&LT; CFSET keyBytes = binaryDe code(hashedKey&安培; padBytes,六角)&GT;
&LT; CFSET finalKey = binaryEn code(keyBytes,BASE64)&GT;
&LT; CFSET解密的解密=(finalText,finalKey的DESede / ECB / PKCS5Padding,BASE64)&GT;
解密的字符串:&LT; cfdump VAR =##解密&GT;

更新:

如果你按照意见的解决办法是改变:

 &LT; CFSET hashedKey =散列(theKeyInBase64,MD5)&GT;

要:

 &LT; CFSET hashedKey =散列(theKey,MD5)&GT;

最后code是这样的:

 &LT; CFSET DBPASSWORD =Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL&GT;
&LT; CFSET finalText =替换(DBPASSWORD,@@ 12,+,全)&GT;
&LT; CFSET theKey =ABCDEFGH&GT;
&LT; CFSET hashedKey =散列(theKey,MD5)&GT;
&LT; CFSET padBytes =左(hashedKey,16)&GT;
&LT; CFSET keyBytes = binaryDe code(hashedKey&安培; padBytes,六角)&GT;
&LT; CFSET finalKey = binaryEn code(keyBytes,BASE64)&GT;
&LT; CFSET解密的解密=(finalText,finalKey的DESede / ECB / PKCS5Padding,BASE64)&GT;
解密的字符串:&LT; cfdump VAR =##解密&GT;


解决方案

看起来有在你的C#功能的一些额外的曲折,你需要处理实现兼容性:


  1. 在.NET函数修改加密的字符串。你需要
    扭转这些变化,从而解密将其识别为有效的base64:

     &LT;!---反向替换密文形式,即#DB.Password#---&GT;
    &LT; CFSET DBPASSWORD =uAugP @@ 12aP4GGBOLCLRqxlNPL1PSHfTNEZ&GT;
    &LT; CFSET finalText =替换(DBPASSWORD,@@ 12,+,全)&GT;


  2. 该功能还使用它创建了一个16字节的密钥哈希值。 CF / JAVA需要的算法 24字节的密钥。所以,你必须首先散列键,垫它适当长度。否则,解密()会抱怨,关键是太小了。

    注:CF还预计最后的关键环节采用base64 EN codeD。错误的无法去code字符串blahblah的提示您输入键不是以base64。

     &LT;! - 哈希和键盘键(即blahblah),然后将其转换为Base64为CF ---&GT;
    &LT; CFSET theKeyInBase64 =rpaSPvIvVLlrcmtzPU9 / c67Gkj7yL1S5&GT;
    &LT; CFSET hashedKey =散列(theKeyInBase64,MD5)&GT;
    &LT; CFSET padBytes =左(hashedKey,16)&GT;
    &LT; CFSET keyBytes = binaryDe code(hashedKey&安培; padBytes,六角)&GT;
    &LT; CFSET finalKey = binaryEn code(keyBytes,BASE64)&GT;


  3. 最后,反馈模式必须匹配。由于.NET code使用的安全性较低的 ECB 模式下,CF code必须使用模式也是如此。

     &LT;! -  .NET code使用的安全性较低ECB模式--- GT&;
    &LT; CFSET解密的解密=(finalText,finalKey的DESede / ECB / PKCS5Padding,BASE64)&GT;
    解密的字符串:&LT; cfdump VAR =##解密&GT;


  4. 另外一个问题需要注意的是编码。在CF,加密/解密始终间preT输入字符串为UTF8,而.NET函数使用的 ASCII 。完全兼容,双方都应该使用相同的编码,在这种情况下UTF8。



更新:

我测试了以上任意8字符键(而不是一个base64字符串)和CF9仍能正常解密的字符串。

  // .NET code
字符串文本=一些文本加密
字符串键=ABCDEFGH
字符串加密= EncryptTripleDES(文字,键);
//结果:加密= Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL
Console.WriteLine(加密= {0},加密的);&LT;!---相同的code,只有加密的文本和重点改变---&GT;
&LT; CFSET DBPASSWORD =Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL&GT;
&LT; CFSET finalText =替换(DBPASSWORD,@@ 12,+,全)&GT;
&LT; CFSET theKey =ABCDEFGH&GT;
&LT; CFSET hashedKey =散列(theKey,MD5)&GT;
....

We are having difficulty decrypting a string in ColdFusion that was previously encrypted with 3DES and C#. Here is the code we used to encrypt the string initially:

    public static string EncryptTripleDES(string plaintext, string key)
    {
    TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
    MD5CryptoServiceProvider hashMD5 = new MD5CryptoServiceProvider();
    DES.Key = hashMD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key));
    DES.Mode = CipherMode.ECB;
    ICryptoTransform DESEncrypt = DES.CreateEncryptor();
    byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(plaintext);

    string EncString = Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
    EncString = EncString.Replace("+", "@@12");

    return EncString;
    }

We have tried using the suggestions here:

TripleDES Encryption - .NET and ColdFusion not playing nice

..with no luck. Here is our CF code and the error:

  <cfset variables.theKey = "blahblah" />
  <cfset variables.theAlgorithm = "DESede/CBC/PKCS5Padding">
  <cfset variables.theEncoding = "Base64">
  <cfset strTest = decrypt(#DB.PASSWORD#, variables.theKey, variables.theAlgorithm, variables.theEncoding)>

Error returned: An error occurred while trying to encrypt or decrypt your input string: '' Can not decode string "blahblah"

So, it looks like it's trying to decrypt the key and not the string, but that's not how the decrypt function is outlined in ColdFusion. Any ideas?

UPDATE: Attempted to use the following CF code, but the error returned is still "An error occurred while trying to encrypt or decrypt your input string: Given final block not properly padded."

<cfset dbPassword  = "Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL">
<cfset finalText   = replace(dbPassword, "@@12", "+", "all")>
<cfset theKey      = "abcdefgh">
<cfset theKeyInBase64 = toBase64(theKey)>
<cfset hashedKey   = hash( theKeyInBase64, "md5" )>
<cfset padBytes    = left( hashedKey, 16 )>
<cfset keyBytes    = binaryDecode( hashedKey & padBytes , "hex" )>
<cfset finalKey    = binaryEncode( keyBytes, "base64" )>
<cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )>
Decrypted String: <cfdump var="#decrypted#">

UPDATE:

The solution if you follow the comments was to change:

<cfset hashedKey   = hash( theKeyInBase64, "md5" )>

To:

<cfset hashedKey   = hash( theKey, "md5" )>

The final code is this:

<cfset dbPassword  = "Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL">
<cfset finalText   = replace(dbPassword, "@@12", "+", "all")>
<cfset theKey      = "abcdefgh">
<cfset hashedKey   = hash( theKey, "md5" )>
<cfset padBytes    = left( hashedKey, 16 )>
<cfset keyBytes    = binaryDecode( hashedKey & padBytes , "hex" )>
<cfset finalKey    = binaryEncode( keyBytes, "base64" )>
<cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )>
Decrypted String: <cfdump var="#decrypted#">

解决方案

Looks like there a few extra twists in your c# function you need to handle to achieve compatibility:

  1. The .NET function modifies the encrypted string. You need to reverse those changes so decrypt will recognize it as valid base64:

    <!--- reverse replacements in encrypted text ie #DB.Password# --->
    <cfset dbPassword = "uAugP@@12aP4GGBOLCLRqxlNPL1PSHfTNEZ">
    <cfset finalText = replace(dbPassword, "@@12", "+", "all")>
    

  2. The function also uses a hash which creates a 16 byte key. CF/java require a 24 byte key for that algorithm. So you must first hash the key and pad it to the proper length. Otherwise, decrypt() will complain the key is too small.

    Note: CF also expects the final key to be base64 encoded. The error Can not decode string "blahblah" suggests your input key is not in base64.

    <!--- hash and pad the key (ie "blahblah"), then convert to base64 for CF --->
    <cfset theKeyInBase64 = "rpaSPvIvVLlrcmtzPU9/c67Gkj7yL1S5">
    <cfset hashedKey   = hash( theKeyInBase64, "md5" )>
    <cfset padBytes    = left( hashedKey, 16 )>
    <cfset keyBytes    = binaryDecode( hashedKey & padBytes , "hex" )>
    <cfset finalKey    = binaryEncode( keyBytes, "base64" )>
    

  3. Finally, the feedback modes must match. Since the .NET code uses the less secure ECB mode, the CF code must use that mode as well.

    <!--- .net code uses the less secure ECB mode --->
    <cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )>
    Decrypted String: <cfdump var="#decrypted#">
    

  4. One other issue to watch out for is encoding. In CF, encrypt/decrypt always interpret the input string as UTF8, whereas the .NET function uses ASCII. For full compatibility, both sides should use the same encoding, in this case UTF8.


Update:

I tested the above with an arbitrary 8 character key (instead of a base64 string) and CF9 still decrypted the string properly.

// .NET Code
String text = "some text to encrypt";
String key = "abcdefgh";
String encrypted = EncryptTripleDES(text, key);
// result: encrypted=Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL
Console.WriteLine("encrypted={0}", encrypted);

<!--- same code, only the encrypted text and key changed ---> 
<cfset dbPassword  = "Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL">
<cfset finalText   = replace(dbPassword, "@@12", "+", "all")>
<cfset theKey      = "abcdefgh">
<cfset hashedKey   = hash( theKey, "md5" )>
.... 

这篇关于解密ColdFusion中的字符串在C#中使用3DES加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆