使用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 中复制它。为此,我们必须更改代码中的一些内容:
- 您的到期日期是
20150101 151515
在Java代码中,但是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=
到目前为止还好。那么红宝石呢?
#!/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模式进行防篡改输入是非常愚蠢的。