当前位置: 首页 > 知识库问答 >
问题:

Java到ruby AES/ECB/PKCS5Padding加密

宋博易
2023-03-14

这是提供的文件:-

加密算法

为了在传输和发布数据时减轻参数调整/修改,商家可以使用Telenor PoC提供的散列密钥加密请求。该加密请求与主请求一起发送,然后在OPS端对主请求进行协调,以检测参数是否更改。加密可以使用以下算法完成:

Put(“StoreID”,“28”);

Fields.Put(“OrderRefNum”,“11001”);

Fields.Put(“ExpiryDate”,“20150101 151515”);

根据地图键按字母顺序对地图字段进行排序

Collections.Sort(fieldNames);

按以下格式创建字符串:amount=10&expirydate=20150101151515&orderrefnum=11001&postbackurl=http://localhost:9081/local/status.php&storeid=28

SecretKeySpec secretKey=新的SecretKeySpec(key.getBytes(),“AES”);

cipher.init(cipher.encrypt_mode,secretKey);

encryptedValue=新字符串(Base64.EncodeBase64(Cipher.DoFinal(value.GetBytes())));

我打了第三方支付门户的帮助热线,他们只提供了足够的帮助告诉我的关键。

如果有人能提供足够的帮助,告诉我什么是步骤5的Ruby等价物,我将不胜感激。谢谢

刚刚在在线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())));
  }
}
encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes())));
^

Location:类encryptData

/tmp/java_ramvov/encryptdata.java:16:错误:找不到符号

encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes())));
                                  ^

符号:方法encodeBase64(字节[])

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

但生成的加密被支付门户拒绝

共有1个答案

殷德本
2023-03-14

使用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将密钥作为十六进制字符串,因此89OUITUPRL4I9H3G应写成其ASCII序列38394F5549545550524C334938483347

输出为:

r7N11xE4HdbJyTByiTDifI1vifvZyNcNfKF+Jo7jEq4rN7c3EiOJxdWOUlCtVXeH
FBTdPSROSmTkUTWfAuOQnHWqe/q/Msd1ykUDIz9eP5L6X6RI0R5UtUXmaakr4klz
1kxEJOjR/WJ5xgd2clBh4iLcYi3caDrCkbD0kRDLQE4=

让我们尝试在Java中复制它。为此,我们必须更改代码中的一些内容:

  1. 您的expiryDate在Java代码中是20150101 151515,但在其他任何地方都是20150101151515。因此,让我们对20150101151515
  2. 进行标准化
  3. base64.encodeBase64()不存在。Java 8内置了Base64编码,代码应该是Base64.getEncoder().EncodeToString(data)
  4. 的返回类型已经是string,因此EncryptedValue=new string(Base64...)是不必要的。
  5. 此外,您需要声明encryptedvalue的类型,然后才能使用它。
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=
#!/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=
 类似资料:
  • 问题内容: 我有一个使用第三方付款门户的在线电子商务网站。在第三方支付门户要求所有人开始使用具有其他支付参数的哈希键之前,支付门户一直工作良好。 现在的问题是,第三方支付门户网站仅提供了一页文档来实现哈希密钥。 这是提供的文档: 加密演算法 为了减轻数据传输和发布过程中的参数调整/修改,商家可以使用Telenor POC提供的哈希密钥对请求进行加密。该加密请求与主请求一起发送,然后在OPS端进行协

  • 我的任务是在一个项目上实现AES加密。参考代码是用Java编写的,需要转换成Python。当我整理笔记写一个问题时,我无意中发现了答案!希望其他人会觉得这很有用,我将在这里把我的笔记作为一个“分享你的知识”的问题提出来。 要求使用具有给定密钥的AES加密消息。下面是参考代码(Java)的简化视图, 如果将上述内容另存为“EncryptAES”。并保留库文件在同一目录中,您可以使用以下命令编译它,

  • 问题内容: 我正在尝试在java中加密数据并在ruby中解密数据。 我的代码是…用Java加密 结果是 我希望在Ruby中解密(加密的字符串) Ruby代码是…(错误) 我希望得到 但它返回错误 我认为问题是cipher.padding和key / iv的类型。但是我不知道如何完成红宝石代码。 请让我知道如何完成此代码。 谢谢。 问题答案: Ruby代码有两个问题。 首先,应该使用AES 128时

  • 问题内容: 我正在尝试在NodeJs中解密。它在Java中工作。但是我无法在Node中实现相同的功能。 节点版本:8.4 请找到我的NodeJs代码: 请找到有效的Java解密代码 我得到了不同的解密文本。在NodeJ中,我无法获得与Java中相同的结果。另外,我无法修改Java加密代码。所以我必须弄清楚Node中的解密。 你能帮我这个忙吗? 问题答案: 这是Java和Node.js中的完整示例,

  • ECB

    ECB 是一个为 Emacs 编辑器提供的文件和代码的浏览器,支持 Java 、C/C++、ELisp、Perl 等源码文件。