首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将ColdFusion加密与Java1.4.2匹配?

如何将ColdFusion加密与Java1.4.2匹配?
EN

Stack Overflow用户
提问于 2010-04-14 15:58:15
回答 1查看 2.6K关注 0票数 7

*甜-感谢Edward的CF Technote,它表明来自ColdFusion的密钥是Base64编码的。关于“修复”,请参见generateKey()

我的任务是使用Java1.4.2来匹配给定的用于加密的ColdFusion代码示例的结果。

已知/给定值:

  • 24字节的密钥
  • 一个16字节的盐(IVorSalt)
  • 编码是十六进制
  • 加密算法为AES/CBC/PKCS5Padding 5填充
  • 示例明文值
  • 示例明文在遍历ColdFusion代码后的加密值。

假设:

  • 没有在ColdFusion代码中指定的迭代次数,所以我假设只有一次迭代
  • 24字节密钥,所以我假设192位加密。

给定/工作的ColdFusion加密代码示例:

代码语言:javascript
复制
<cfset ThisSalt = "16byte-salt-here">
<cfset ThisAlgorithm = "AES/CBC/PKCS5Padding">
<cfset ThisKey = "a-24byte-key-string-here">
<cfset thisAdjustedNow = now()>
<cfset ThisDateTimeVar = DateFormat( thisAdjustedNow , "yyyymmdd" )>
<cfset ThisDateTimeVar = ThisDateTimeVar & TimeFormat( thisAdjustedNow , "HHmmss" )>
<cfset ThisTAID = ThisDateTimeVar & "|" & someOtherData>
<cfset ThisTAIDEnc = Encrypt( ThisTAID , ThisKey , ThisAlgorithm , "Hex" , ThisSalt)>

我的Java1.4.2加密/解密代码拖拽:

代码语言:javascript
复制
package so.example;

import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.*;

public class SO_AES192 {

private static final String _AES = "AES";
private static final String _AES_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding";
private static final String KEY_VALUE = "a-24byte-key-string-here";
private static final String SALT_VALUE = "16byte-salt-here";
private static final int ITERATIONS = 1;

private static IvParameterSpec ivParameterSpec;

public static String encryptHex(String value) throws Exception {
    Key key = generateKey();

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding);
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes());
    c.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);

    String valueToEncrypt = null;
    String eValue = value;
    for (int i = 0; i < ITERATIONS; i++) {
//            valueToEncrypt = SALT_VALUE + eValue; // pre-pend salt - Length > sample length
        valueToEncrypt =  eValue;     // don't pre-pend salt  Length = sample length
        byte[] encValue = c.doFinal(valueToEncrypt.getBytes());
        eValue =  Hex.encodeHexString(encValue);
    }
    return eValue;
}

public static String decryptHex(String value) throws Exception {
    Key key = generateKey();

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding);
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes());
    c.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);

    String dValue = null;
    char[] valueToDecrypt = value.toCharArray();
    for (int i = 0; i < ITERATIONS; i++) {
        byte[] decordedValue = Hex.decodeHex(valueToDecrypt);
        byte[] decValue = c.doFinal(decordedValue);
//            dValue = new String(decValue).substring(SALT_VALUE.length()); // when salt is pre-pended
        dValue = new String(decValue);   // when salt is not pre-pended
        valueToDecrypt = dValue.toCharArray();
    }
    return dValue;
}

private static Key generateKey() throws Exception {
    // Key key = new SecretKeySpec(KEY_VALUE.getBytes(), _AES); // this was wrong
    Key key = new SecretKeySpec(new BASE64Decoder().decodeBuffer(keyValueString), _AES); // had to un-Base64 the 'known' 24-byte key.
    return key;
}

}

我不能创建匹配的加密值,也不能解密给定的加密值。我的猜测是,这与我如何处理初始向量/盐有关。

我不太懂密码,但我想我应该能够获取示例明文,并在Java中生成与ColdFusion生成的加密值相同的值。我能够用我的Java代码加密/解密我自己的数据(所以我是一致的),但是我不能匹配或解密ColdFusion示例加密的值。

我可以访问本地the服务,该服务可以测试加密的输出。给定的ColdFusion输出示例很好地传递/解密(当然)。如果我试图用我的Java代码(使用实际的密钥和salt)解密同一个示例,就会得到一个“给定的最后块没有正确填充”错误。当我将加密尝试(使用实际密钥和salt)传递给测试webservice时,我得到了相同的净结果。

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-04-14 17:32:57

是Coldfusion ThisKey中的值:

代码语言:javascript
复制
<cfset ThisKey = "a-24byte-key-string-here">

从java generateKey()函数返回的完全相同的字符串?我认为,如果生成的加密文本是相同的,则它们必须是相同的字符串。

要在CF中使用这样的固定密钥,您可能需要在强加密时遵循CF technote中的以下内容:

您可能想要生成自己的密钥,原因有两个:

  1. 您想要匹配其他加密软件的详细信息。
  2. 您希望通过面向模式的密码分析技术来提高加密数据的抗破解能力。

例如,要创建一个具有十六进制值的AES算法使用的32字节密钥:

8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c

您可以使用ColdFusion函数BinaryDecode和ToBase64来创建键:

代码语言:javascript
复制
<cfset myKey =
ToBase64(BinaryDecode("8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c","Hex")>
<cfset encrypted =Encrypt(myString, myKey, "AES")>

编辑:刚刚意识到关键(正如您在评论中提到的)是base64,所以如果generateKey中的"generateKey“方法如下所示:

代码语言:javascript
复制
private static Key generateKey() throws Exception {
final byte[] decodedKey = new BASE64Decoder().decodeBuffer(KEY_VALUE);
final Key key = new SecretKeySpec(decodedKey, _AES);
return key;
}

你应该是黄金。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2638967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档