简体   繁体   中英

ColdFusion - cfusion_encrypt() and cfusion_decrypt() - C# alternative

I have a database with user passwords that are encrypted via cfusion_encrypt(). I need to do a login alternative for the ColdFusion code in C#. Is there any easy way how to emulate this in C# so I will be able to compare encrypted values of user passwords and match them to the ColdFusion values?

The poorly named cfusion_encrypt() is not encryption at all. It is an internal, legacy obfuscation algorithm, whose use is strongly discouraged.

Essentially it just xor's the bytes, similar to the method described here (Ignore the mention of cfmx_compat , that is a different legacy algorithm). It extracts the bytes of a plain text string. Then pads the supplied key string to the same length , and again extracts the bytes. Finally it xor's the two byte arrays and encodes the result as hex:

 // xor bytes
 byte[] result = new byte[textBytes.Length];
 for (int i = 0; i < textBytes.Length; i++) {
      results[i] = (byte)(textBytes[i] ^ keyBytes [i]);
 } 
 // encode result as hex
 String hexResult = BitConverter.ToString(results).Replace("-", "");

The cfusion_decrypt() function does essentially the same thing only decoding the hex string into bytes first, and returns the "de-obfuscated" result as a plain string instead of hex.

Now you can see why its use is discouraged. As @MartyPine and others suggested, the better option is to have the CF side make a backup, then run the passwords through cfusion_decrypt and hash() them instead. Not only is it a better way to store passwords, it also has the benefit of being compatible with C#, or any other language that supports the standard algorithms.

This may not answer your question, but the best bet from what I can tell would be to code up a Coldfusion loop to:

  1. cfusion_decrypt() the passwords
  2. hash the passwords in a C# friendly format

I'm not aware of any C# native equivalents to cfusion_decrypt and cfusion_encrypt, but hopefully the folks here might be able to point you towards one.

If you require the built-in "cfusion_encrypt" & "cfusion_decrypt" undocumented functions that Adobe silently deprecated in ColdFusion 11, a developer converted them into UDFs back in 2005.

http://www.barneyb.com/barneyblog/2005/10/28/cfusion_encryptcfusion_decrypt-udfs/

<cfscript>
function binaryXOR(n1, n2){
    n1 = formatBaseN(n1, 2);
    n2 = formatBaseN(n2, 2);
    return inputBaseN(replace(n1 + n2, 2, 0, "all"), 2);
}
function fusion_encrypt(string, key){
    var i = "";
    var result = "";
    key = repeatString(key, ceiling(len(string) / len(key)));
    for (i=1;i LTE len(string);i=i+1) {
        result = result & rJustify(formatBaseN(binaryXOR(asc(mid(string, i, 1)), asc(mid(key, i, 1))), 16), 2);
    }
    return ucase(replace(result, " ", "0", "all"));
}
function fusion_decrypt(string, key){
    var i = "";
    var result = "";
    key = repeatString(key, ceiling(len(string) / 2 / len(key)));
    for (i=2;i LTE len(string);i=i+2) {
        result = result & chr(binaryXOR(inputBaseN(mid(string, i - 1, 2), 16), asc(mid(key, i / 2, 1))));
    }
    return result;
}
</cfscript>

Here's sample script on how to test it:

<cfset key = "test">
<cfoutput>
<table border=1 cellspacing=0>
<thead>
    <tr><th>String</th>
    <th>cfusion_encrypt</th>
    <th>fusion_encrypt</th>
    <th>cfusion_decrypt</th>
    <th>fusion_decrypt</th>
    </tr>
</thead>
<tbody>
<cfloop list="Adobe,ColdFusion,is,damn cool!" index="i">
    <tr>
    <td>#i#</td>
    <td><cftry>#cfusion_encrypt(i, key)#<cfcatch>ERROR</cfcatch></cftry></td>
    <td><cftry>#fusion_encrypt(i, key)#<cfcatch>ERROR</cfcatch></cftry></td>
    <td><cftry>#cfusion_decrypt(cfusion_encrypt(i, key), key)#<cfcatch>ERROR</cfcatch></cftry></td>
    <td><cftry>#fusion_decrypt(fusion_encrypt(i, key), key)#<cfcatch>ERROR</cfcatch></cftry></td>
    </tr>
</cfloop>
</tbody>
</table>
</cfoutput>

Probably the simplest solution is to create ColdFusion service layer which will interact with your db, but you need to work on security for this service, of course if you want to keep passwords the way they are now.

If you don't want a CF service layer, then what you need to do is to figure out what kind of encryption is being used. If it is one of the common hash algorithms like: MD5 SHA1 SHA256 SHA384 SHA512 then you'll have a chance of solving this.

I found an old article on www.fusionauthority.com which stated:

CFusion_Encrypt()/CFusion_Decrypt() are 'administrative' in ColdFusion and are not documented anywhere other than here . Allaire does not suggest using them and offers no support for their use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM