簡體   English   中英

Java到ruby的AES / ECB / PKCS5Padding加密

[英]Java to ruby AES/ECB/PKCS5Padding encryption

我有一個使用第三方付款門戶的在線電子商務網站。 在第三方支付門戶要求所有人開始使用具有其他支付參數的哈希鍵之前,支付門戶一直運行良好。

現在的問題是,第三方支付門戶網站僅提供了一頁文檔來實現哈希密鑰。

這是提供的文檔:

加密演算法

為了減輕數據傳輸和發布過程中的參數調整/修改,商家可以使用Telenor POC提供的哈希密鑰對請求進行加密。 該加密的請求與主請求一起發送,然后在OPS端進行協調以檢測參數是否已更改。 可以使用以下算法進行加密:

  1. 創建屬於請求的所有字段的映射。Map fields = new HashMap();

    fields.put(“ amount”,“ 10”);

    fields.put(“ storeId”,“ 28”);

    fields.put(“ orderRefNum”,“ 11001”);

    fields.put(“ expiryDate”,“ 20150101 151515”);

    fields.put(“ postBackURL”,“ http:// localhost:9081 / local / status.php ”);

  2. 從第一步中創建的地圖中獲取字段名稱列表

    列出fieldNames = new ArrayList(fields.keySet());

  3. 根據地圖關鍵字按字母順序對地圖字段進行排序

    Collections.sort(fieldNames);

  4. 創建以下格式的字符串:amount = 10&expiryDate = 20150101151515&orderRefNum = 11001&postBackURL = http:// localhost:9081 / local / status.php&storeId = 28

  5. 使用AES / ECB / PKCS5Padding算法使用上一步中生成的密鑰和字符串進行加密

    密碼cipher = Cipher.getInstance(“ AES / ECB / PKCS5Padding”);

    SecretKeySpec secretKey =新的SecretKeySpec(key.getBytes(),“ AES”);

    cipher.init(Cipher.ENCRYPT_MODE,secretKey);

    加密的值=新的String(Base64.encodeBase64(cipher.doFinal(value.getBytes())));

現在另一個問題是我沒有Java經驗。

我打了第三方支付門戶服務熱線,他們僅對告訴我鑰匙有幫助。

如果有人可以幫助我告訴我第5步的Ruby等效標准,我將不勝感激。 謝謝

剛剛嘗試了在線Java編譯器上提供的代碼:-

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) {

    String data="amount=10&expiryDate=20150101 151515&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);
    encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes())));
  }
}

這是錯誤:

/tmp/java_Ramvov/encryptData.java:16:錯誤:找不到符號

encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes())));
^

符號:變量encryptedValue

位置:類cryptoData

/tmp/java_Ramvov/encryptData.java:16:錯誤:找不到符號

encryptedValue = new String(Base64.encodeBase64(cipher.doFinal(data.getBytes())));
                                  ^

符號:方法encodeBase64(byte [])

位置:Base64類

2個錯誤

任何幫助將不勝感激

我也嘗試在ruby中重現此Java代碼:-

data = "amount=10&expiryDate=20150101151515&orderRefNum=11001&postBackURL=http://localhost:9081/local/status.php&storeId=28"                                                                                                                                            
cipher = OpenSSL::Cipher.new("AES-128-ECB")
cipher.encrypt()
cipher.key = "89OUITUPRL4I9H3G"
crypt = cipher.update(data) + cipher.final()
crypt_string = (Base64.encode64(crypt))

但是生成的加密被付款門戶拒絕

使用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復制它。 為此,我們必須在您的代碼中進行一些更改:

  1. 您的expiryDate在Java代碼中為20150101 151515 ,在其他地方為20150101151515 因此,讓我們在20150101151515上進行20150101151515
  2. Base64.encodeBase64()不存在。 Java 8內置了Base64編碼,代碼應為Base64.getEncoder().encodeToString(data)
  3. 該類型的返回類型已經是字符串,因此不需要encryptedValue = new String(Base64...)
  4. 此外,你需要聲明的類型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與openssl一樣需要密鑰,因為ruby加密通常在幕后使用openssl。 因此將鍵定義更改為

key = "38394f5549545550524c334938483347"
key = [key].pack('H*')

現在打印:

r7N11xE4HdbJyTByiTDifI1vifvZyNcNfKF+Jo7jEq4rN7c3EiOJxdWOUlCt
VXeHFBTdPSROSmTkUTWfAuOQnHWqe/q/Msd1ykUDIz9eP5L6X6RI0R5UtUXm
aakr4klz1kxEJOjR/WJ5xgd2clBh4iLcYi3caDrCkbD0kRDLQE4=

除了換行符位置,它與其他兩個輸出相同。 希望您能夠與另一邊進行交流,並記住:

使用ECB模式進行防篡改輸入非常愚蠢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM