在 C# 中解密使用 3DES 加密的 ColdFusion 中的字符串

2023-12-09

我们在 ColdFusion 中解密之前使用 3DES 和 C# 加密的字符串时遇到困难。这是我们最初用来加密字符串的代码:

    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;
    }

我们已尝试使用此处的建议:

TripleDES 加密 - .NET 和 ColdFusion 表现不佳

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

  <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)>

返回错误:尝试加密或解密输入字符串时发生错误:“无法解码字符串“blahblah”

因此,看起来它正在尝试解密密钥而不是字符串,但这并不是 ColdFusion 中解密函数的概述。有任何想法吗?

UPDATE:尝试使用以下 CF 代码,但返回的错误仍然是“尝试加密或解密输入字符串时发生错误:给定最终块未正确填充。”

<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:

如果您遵循评论,解决方案是更改:

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

To:

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

最终代码是这样的:

<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#">

看起来您的 c# 函数中需要处理一些额外的问题才能实现兼容性:

  1. .NET 函数修改加密的字符串。你需要 反转这些更改,以便解密将其识别为有效的 base64:

    <!--- reverse replacements in encrypted text ie #DB.Password# --->
    <cfset dbPassword = "uAugP@@12aP4GGBOLCLRqxlNPL1PSHfTNEZ">
    <cfset finalText = replace(dbPassword, "@@12", "+", "all")>
    
  2. 该函数还使用哈希来创建 16 字节密钥。 CF/java 需要一个24字节密钥对于该算法。所以你必须首先散列密钥并将其垫至合适的长度。否则,decrypt() 会抱怨密钥太小。

    注意:CF 还期望最终密钥采用 Base64 编码。错误无法解码字符串“blahblah”表明您的输入键不是 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. 最后,反馈模式必须匹配。由于 .NET 代码使用不太安全的ECB模式,CF 代码也必须使用该模式。

    <!--- .net code uses the less secure ECB mode --->
    <cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )>
    Decrypted String: <cfdump var="#decrypted#">
    
  4. 另一个需要注意的问题是编码。在 CF 中,加密/解密始终将输入字符串解释为 UTF8,而 .NET 函数使用ASCII。为了完全兼容,双方应使用相同的编码,在本例中为 UTF8。


Update:

我使用任意 8 个字符密钥(而不是 Base64 字符串)测试了上述内容,CF9 仍然正确解密了该字符串。

// .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" )>
.... 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中解密使用 3DES 加密的 ColdFusion 中的字符串 的相关文章

随机推荐