gpt4 book ai didi

java - 如何像 SecretKeySpec 一样加密 ruby​​ 中的数据?

转载 作者:数据小太阳 更新时间:2023-10-29 08:03:07 25 4
gpt4 key购买 nike

我正在尝试使用 Cipher 和 AES 算法对 ruby​​ 中的字符串进行加密。我有用 Java 编写的示例。我已从这个示例中获得帮助并用 Java 编写了代码,但无法获得与在 JAVA 中相同的输出。

以下是用java编写的代码

import java.util.Base64;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.util.Arrays;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HelloWorld {
public static final String PHONENUMBER_PARAM = "phoneNumber";
public static final String PIN_PARAM ="pin";

public static final String MERCHANTID_PARAM = "merchantId";

public static void main(String args[]) throws Exception {

String phoneNumber ="+917738995286";
String pin ="5577";

String merchantId ="527425858";
String encodedKey ="vPDkdTDrcygLPROzd1829A==";

String payLoad = PHONENUMBER_PARAM + "=" + URLEncoder.encode(phoneNumber, "UTF-8")+ "&" + PIN_PARAM + "=" + URLEncoder.encode(pin, "UTF-8") ;

byte[] decodedKey = Base64.getDecoder().decode(encodedKey.getBytes());

Key encryptionKey = new SecretKeySpec(decodedKey, "AES");

byte[] utf8Bytes = payLoad.getBytes("utf-8");

byte[] encryptedBody = encrypt(encryptionKey, utf8Bytes);
String encryptedData = new String(Base64.getEncoder().encode(encryptedBody));

System.out.println("encryptedData:" + encryptedData);
}
private static byte[] encrypt(Key encryptionKey, byte[] data) throws Exception {
Cipher c = Cipher.getInstance("AES");
c.init(1, encryptionKey);
return c.doFinal(data);
}
}

这段代码的输出是

encryptedData:lE40HlECbxU/mWRivF/+Szm3PprMoLW+Y7x911GczunakbG8l+A2JVEEP8gTw6xy

我尝试用 ruby​​ 编写相同的代码。 ruby 代码是:

payLoad = "phoneNumber=%2B917738995286&pin=5577"

encodedKey = "vPDkdTDrcygLPROzd1829A=="

decodedKey = Base64.decode64(encodedKey)

dKey = decodedKey.each_byte.map { |b| b.to_s(16) }.join

cipher = OpenSSL::Cipher.new('aes128').encrypt
encryptionKey = cipher.update(dKey)
encryptionKey<< cipher.final


utf8Bytes = payLoad.bytes
uKey = utf8Bytes.map { |b| b.to_s(16) }.join

scipher = OpenSSL::Cipher.new('aes128').encrypt
scipher.key = encryptionKey
encryptedBody = scipher.update(uKey)
encryptedBody<< scipher.final

encryptedData = Base64.encode64(encryptedBody)

这段代码的输出是

CqFmCKJ004PsoXi2tDCTBmx7/iTHVyDsFH9y8NWNrEP3k3bOQp7h8uyl/a7Z\nYi9ZmcXSspo6FCyCo6fJIwPohg==\n

不知道哪里出错了。我已经工作了 2 天,但无法得到任何答案。任何帮助都会很棒。提前致谢。

最佳答案

以下版本输出与您的 Java 代码相同的结果:

# crypt.rb
require 'base64'
require 'openssl'

payLoad = "phoneNumber=%2B917738995286&pin=5577"
encodedKey = "vPDkdTDrcygLPROzd1829A=="

decodedKey = Base64.decode64(encodedKey)

scipher = OpenSSL::Cipher.new('aes-128-ecb').encrypt
scipher.key = decodedKey
encryptedBody = scipher.update(payLoad)
encryptedBody << scipher.final

encryptedData = Base64.encode64(encryptedBody)
puts encryptedData


$ ruby crypt.rb
# => lE40HlECbxU/mWRivF/+Szm3PprMoLW+Y7x911GczunakbG8l+A2JVEEP8gT
# w6xy

与您的 ruby​​ 脚本版本的显着差异:

  • 必须指定密码模式。问题是 Java defaults to the ECB mode而 ruby​​ 默认为 CBC 模式。顺便说一句,今天欧洲央行模式被认为不太安全,你实际上 should not use it .

  • 在 ruby​​ 中,您尝试重新加密加密 key 的 Base64 解码版本,而在 Java 版本中您不会这样做。

  • 在ruby中,无需进行字符串到字节的转换,直接加密即可。

因此,尽管这两个脚本现在输出相同的加密数据,但我会强烈考虑更改 AES 操作模式,以真正保持安全。

关于java - 如何像 SecretKeySpec 一样加密 ruby​​ 中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36939277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com