如何使用与SecretKeySpec相同的ruby中的数据加密? [英] How to Encrypt data in ruby same as SecretKeySpec?

查看:129
本文介绍了如何使用与SecretKeySpec相同的ruby中的数据加密?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用AES算法使用Cipher加密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; 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆