我将使用AES算法,使用Ruby中的Cipher对字符串进行加密。我有一个在Java中编写的示例,并参考此示例编写了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
不知道哪里出了问题。我已经工作了两天,但是没有任何答案。如果有帮助会很棒。先谢谢了。
puts some_value
来调试每一步并找出差异。 - joewoodwardCipher.getInstance("AES");
可能会根据默认安全提供程序而产生不同的加密方式。它很可能会产生"AES/ECB/PKCS5Padding"
,但不一定如此。如果发生更改,则会失去不同 JVM 之间的兼容性。 - Artjom B.