Java to ruby AES / ECB / PKCS5Padding加密
我有一个使用第三方支付门户的在线电子商务网站。 支付门户网站工作正常,直到第三方支付门户网站要求所有人开始使用带有其他支付参数的哈希密钥。
现在的问题是第三方支付门户网站只提供了一个用于实现哈希密钥的页面文档。
这是提供的文件: –
加密演算法
为了在传输和发布数据时减轻参数回火/修改,商家可以使用Telenor POC提供的散列密钥加密请求。 该加密请求与主请求一起发送,然后主请求在OPS端协调以检测参数是否被改变。 加密可以使用以下算法完成:
创建作为请求一部分的所有字段的映射Map fields = new HashMap();
fields.put(“amount”,“10”);
fields.put(“storeId”,“28”);
fields.put(“orderRefNum”,“11001”);
fields.put(“expiryDate”,“20150101 151515”);
fields.put(“postBackURL”,“ http:// localhost:9081 / local / status.php ”);
从第一步中创建的地图中获取字段名称列表
List fieldNames = new ArrayList(fields.keySet());
按字母顺序基于地图键对地图字段进行排序
Collections.sort(FIELDNAMES);
按以下格式创建字符串:amount = 10&expiryDate = 20150101151515&orderRefNum = 11001&postBackURL = http:// localhost:9081 / local / status.php&storeId = 28
使用AES / ECB / PKCS5Padding算法使用上一步中生成的密钥和字符串进行加密
密码密码= Cipher.getInstance(“AES / ECB / PKCS5Padding”);
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),“AES”);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);
encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(value.getBytes())));
现在另一个问题是我没有任何Java经验。
我打电话给第三方支付门户热线,他们只是有用的告诉我密钥。
如果有人能够提供足够的帮助,告诉我Ruby的等同于第5步,我将不胜感激。 谢谢
刚试过在线java编译器提供的代码: –
import java.security.Key; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class encryptData { public static void main(String[] args) { String data="amount=10&expiryDate=20150101 151515&orderRefNum=11001&postBackURL=http://localhost:9081/local/status.php&storeId=28"; String key="89OUITUPRL3I8H3G"; Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes()))); } }
这是错误: –
/tmp/java_Ramvov/encryptData.java:16:错误:找不到符号
encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes()))); ^
symbol:变量encryptedValue
location:class encryptData
/tmp/java_Ramvov/encryptData.java:16:错误:找不到符号
encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes()))); ^
符号:方法encodeBase64(byte [])
位置:类Base64
2个错误
任何帮助将不胜感激
我也尝试在ruby中重现这个java代码: –
data = "amount=10&expiryDate=20150101151515&orderRefNum=11001&postBackURL=http://localhost:9081/local/status.php&storeId=28" cipher = OpenSSL::Cipher.new("AES-128-ECB") cipher.encrypt() cipher.key = "89OUITUPRL4I9H3G" crypt = cipher.update(data) + cipher.final() crypt_string = (Base64.encode64(crypt))
但是生成的加密被支付门户拒绝
使用ECB模式进行防篡改输入非常愚蠢。
话虽如此,并且知道这不是你的错,因为首先不是你的想法,而你只是想让代码工作,让我们请一个独立的团队给我们一个参考点:
echo -n "amount=10&expiryDate=20150101151515&orderRefNum=11001&postBackURL=http://localhost:9081/local/status.php&storeId=28" | openssl enc -K 38394f5549545550524c334938483347 -aes-128-ecb -base64
请注意,openssl将密钥作为hex字符串,因此89OUITUPRL4I9H3G
写为其ASCII序列38394f5549545550524c334938483347
输出是:
r7N11xE4HdbJyTByiTDifI1vifvZyNcNfKF+Jo7jEq4rN7c3EiOJxdWOUlCtVXeH FBTdPSROSmTkUTWfAuOQnHWqe/q/Msd1ykUDIz9eP5L6X6RI0R5UtUXmaakr4klz 1kxEJOjR/WJ5xgd2clBh4iLcYi3caDrCkbD0kRDLQE4=
让我们尝试在Java中复制它。 为此,我们必须更改代码中的一些内容:
- 您的expiryDate在Java代码中是
20150101 151515
,在其他地方是20150101 151515
。 所以让我们在20150101151515
上实现20150101151515
-
Base64.encodeBase64()
不存在。 Java 8内置Base64编码,代码应为Base64.getEncoder().encodeToString(data)
- 返回类型已经是字符串,所以
encryptedValue = new String(Base64...)
是不必要的。 - 此外,您需要在使用之前声明
encryptedValue
的类型。
尽管如此,这在Java 8中编译:
import java.security.Key; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class encryptData { public static void main(String[] args) throws Exception { String data="amount=10&expiryDate=20150101151515&orderRefNum=11001&postBackURL=http://localhost:9081/local/status.php&storeId=28"; String key="89OUITUPRL3I8H3G"; Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] plaintext = data.getBytes(); byte[] ciphertext = cipher.doFinal(plaintext); String encryptedValue = Base64.getEncoder().encodeToString(ciphertext); System.out.println(encryptedValue); } }
和打印(我添加的换行符):
r7N11xE4HdbJyTByiTDifI1vifvZyNcNfKF+Jo7jEq4rN7c3EiOJxdWOUlCtVXeH FBTdPSROSmTkUTWfAuOQnHWqe/q/Msd1ykUDIz9eP5L6X6RI0R5UtUXmaakr4klz 1kxEJOjR/WJ5xgd2clBh4iLcYi3caDrCkbD0kRDLQE4=
好的到目前为止。 ruby怎么样?
#!/usr/bin/ruby require 'openssl' require 'base64' data = "amount=10&expiryDate=20150101151515&orderRefNum=11001&postBackURL=http://localhost:9081/local/status.php&storeId=28" key = "89OUITUPRL4I9H3G" cipher = OpenSSL::Cipher.new("AES-128-ECB") cipher.encrypt() cipher.key = key crypt = cipher.update(data) + cipher.final crypt_string = (Base64.encode64(crypt)) puts crypt_string
这打印:
mp8WVhyUHFDqvJKaRXbYKbZT1920TNboRpFLUdPaYsWTkiQ2fhN/tCL6wvtI B9/Mu08McaKTVIWYeQAfVR5XcUKdeQ+CBcJJRs5krLBjtjiMNlBUq9JpCUaC 0eclfDMaGTE+Z4XSafjPictWzTG/Ye+vkJWC23yxW1zSjBnYBfg=
为什么ruby代码不起作用? 我怀疑ruby想要的密钥与openssl一样,因为ruby crypto通常在引擎盖下使用openssl。 所以将密钥定义更改为
key = "38394f5549545550524c334938483347" key = [key].pack('H*')
现在打印:
r7N11xE4HdbJyTByiTDifI1vifvZyNcNfKF+Jo7jEq4rN7c3EiOJxdWOUlCt VXeHFBTdPSROSmTkUTWfAuOQnHWqe/q/Msd1ykUDIz9eP5L6X6RI0R5UtUXm aakr4klz1kxEJOjR/WJ5xgd2clBh4iLcYi3caDrCkbD0kRDLQE4=
除了换行符位置与其他两个位置的输出相同。 希望你能够正确地与对方沟通,并记住:
使用ECB模式进行防篡改输入非常愚蠢。