如何使用与SecretKeySpec相同的ruby中的数据加密? [英] How to Encrypt data in ruby same as SecretKeySpec?
问题描述
以下是用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; X-45454545 X-4545 X-4545 X- 20045 X-454545 X-454545 X-
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());
密钥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')加密
encryptionKey = cipher.update(dKey)
encryptionKey< < cipher.final
utf8Bytes = payLoad.bytes
uKey = utf8Bytes.map {| b | b.to_s(16)} .join
scipher = OpenSSL :: Cipher.new('aes128')加密
scipher.key = encryptionKey
encryptedBody = scipher.update (uKey)
encryptedBody<<< scipher.final
encryptedData = Base64.encode64(encryptedBody)
此代码的输出是
CqFmCKJ004PsoXi2tDCTBmx7 / iTHVyDsFH9y8NWNrEP3k3bOQp7h8uyl / a7Z\\\
Y9ZmcXSspo6FCyCo6fJIwPohg == \\\
不知道错误在哪里。我已经工作了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')加密
scipher.key = decodedKey
encryptedBody = scipher.update(payLoad)
encryptedBody<< scipher.final
encryptedData = Base64.encode64(encryptedBody)
放入加密数据
$ ruby crypt.rb
#=> lE40HlECbxU / mWRivF / + Szm3PprMoLW + Y7x911GczunakbG8l + A2JVEEP8gT
#w6xy
与你的红宝石有显着差异脚本版本:
-
您必须指定加密模式。问题是Java 默认为ECB模式,而ruby默认为CBC模式。顺便说一下,今天ECB模式被认为是不太安全的,而实际上不应该使用它 。
-
在ruby中,您尝试重新加密Base64解码版本的加密密钥,这是您不在Java中执行的
-
在ruby中,没有必要对字节进行字节转换,您可以马上加密字符串。
所以尽管现在这两个脚本输出了相同的加密数据,但我强烈的考虑改变AES操作模式,实际上保持安全。 p>
I am trying to encrypt a string in ruby using Cipher with AES algorithm. I have example written in Java. I have taken help from this example and written code in Java but not able to get the same output as in JAVA.
Following is the code written in 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);
}
}
Output of this code is
encryptedData:lE40HlECbxU/mWRivF/+Szm3PprMoLW+Y7x911GczunakbG8l+A2JVEEP8gTw6xy
I tried to write the same code in ruby. Ruby Code is:
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)
Output of this code is
CqFmCKJ004PsoXi2tDCTBmx7/iTHVyDsFH9y8NWNrEP3k3bOQp7h8uyl/a7Z\nYi9ZmcXSspo6FCyCo6fJIwPohg==\n
Don't know where is the error. I have already worked for 2 days but not able to get any answer. Any help will be great. Thanks in advance.
The following version outputs the same result as your Java code:
# 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
Notable differences from your ruby script version:
You must specify the cipher mode. The problem is that Java defaults to the ECB mode whereas ruby defaults to the CBC mode. By the way, the ECB mode is considered less-secure today and you actually should not use it.
In ruby, you tried to re-encrypt the Base64-decoded version of your encryption key, which is something you don't do in the Java version.
In ruby, there is no need to do the string to byte conversions, you can encrypt strings right away.
So, although the two scripts output the same encrypted data now, I would strongly consider changing the AES mode of operation, to actually stay secure.
这篇关于如何使用与SecretKeySpec相同的ruby中的数据加密?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!