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

Decrypting a string in ColdFusion encrypted with 3DES in C#(在 C# 中解密用 3DES 加密的 ColdFusion 中的字符串)

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

问题描述

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

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 加密 - .NET 和 ColdFusion 效果不佳

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

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

错误返回:尝试加密或解密输入字符串时出错:''无法解码字符串blahblah"

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

所以,看起来它是在尝试解密密钥而不是字符串,但这不是 ColdFusion 中解密函数的概述方式.有什么想法吗?

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?

更新:尝试使用以下 CF 代码,但返回的错误仍然是尝试加密或解密您的输入字符串时发生错误:未正确填充最终块."

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

更新:

如果您关注评论,解决方案是更改:

The solution if you follow the comments was to change:

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

收件人:

<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# 函数中需要处理一些额外的曲折以实现兼容性:

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

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

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

  • 该函数还使用创建 16 字节密钥的哈希.CF/java 需要 24 字节密钥.因此,您必须首先对密钥进行哈希处理,然后 将其填充到适当的长度.否则,decrypt() 会抱怨密钥太小.

  • 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.

    注意:CF 还期望最终密钥是 base64 编码的.错误 Can not decode string "blahblah" 表明您的输入键不在 base64 中.

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

  • 最后,反馈模式必须匹配.由于 .NET 代码使用安全性较低的 ECB 模式,CF 代码也必须使用该模式.

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

  • 另一个需要注意的问题是编码.在 CF 中,加密/解密始终将输入字符串解释为 UTF8,而 .NET 函数使用 ASCII.为了完全兼容,双方应使用相同的编码,在本例中为 UTF8.

  • 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.

    <小时>

    更新:

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

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

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

  • 本文标题为:在 C# 中解密用 3DES 加密的 ColdFusion 中的字符串

    基础教程推荐