*** 好极了——感谢 Edward Smith 的 CF Technote,指出来自 ColdFusion 的 key 是 Base64 编码的。请参阅 generateKey() 以了解“修复”
我的任务是使用 Java 1.4.2 来匹配给定 ColdFusion 代码示例的结果以进行加密。
已知/给定值:
假设:
给定/有效的 ColdFusion 加密代码示例:
<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)>
我的 Java 1.4.2 加密/解密代码 swag:
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;
}
}
我无法创建匹配的加密值,也无法解密给定的加密值。我猜这与我处理初始 vector/盐的方式有关。
我不是很精通加密,但我认为我应该能够采用示例明文并在 Java 中生成与 ColdFusion 生成的相同的加密值。我能够使用我的 Java 代码加密/解密我自己的数据(所以我是一致的)但我无法匹配或解密 ColdFusion 示例加密值。
我可以访问可以测试加密输出的本地网络服务。给定的 ColdFusion 输出样本可以很好地通过/解密(当然)。如果我尝试用我的 Java 代码(使用实际的 key 和盐)解密同一个样本,我会收到“给定的最终 block 未正确填充”错误。当我将加密尝试(使用实际 key 和盐)传递给测试 Web 服务时,我得到了相同的最终结果。
有什么想法吗?
最佳答案
Coldfusion中的值就是ThisKey:
<cfset ThisKey = "a-24byte-key-string-here">
从 java generateKey() 函数返回的字符串是否完全相同?我相信它们必须是相同的字符串才能使生成的加密文本相同。
要在 CF 中使用固定 key ,您可能需要按照 CF technote 中的说明进行操作关于强加密:
You may want to generate your own key for two reasons:
- 您想匹配其他加密软件的详细信息。
- 您想提高抗裂性 面向模式的加密数据 密码分析技术。
例如,创建一个32字节的 key 与 AES 算法一起使用 十六进制值:
8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c
您将使用 ColdFusion 函数 BinaryDecode 和 ToBase64 来创建 关键:
<cfset myKey =
ToBase64(BinaryDecode("8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c","Hex")>
<cfset encrypted =Encrypt(myString, myKey, "AES")>
编辑:刚刚意识到 key (如您在评论中提到的)是 base64,因此如果 Java 中的“generateKey”方法如下所示:
private static Key generateKey() throws Exception {
final byte[] decodedKey = new BASE64Decoder().decodeBuffer(KEY_VALUE);
final Key key = new SecretKeySpec(decodedKey, _AES);
return key;
}
你应该是金色的。
关于java - 如何将ColdFusion 加密与Java 1.4.2 相匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2638967/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为