2016-12-16 83 views
0

有一個支付網關,我正在工作,他們有一個Java演示工作,但我想在PHP中實現這個。Java RSA到PHP phpseclib RSA

支付網關通過使用帶有隨機生成密鑰的3DES加密有效負載。 通過使用支付網關的PUBLIC密鑰使用RSA加密該密鑰。

問題是,當我使用php腳本對該密鑰進行RSA加密時,支付網關不能正確提取密鑰,顯然PHP上的RSA加密工作不正常。

這裏的RSA加密的Java版本:

public static byte[] encrypt(byte[] data, String pubKey64) { 

    try { 
     byte[] key = Toolkit.base64Decode(pubKey64); 
     KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA"); 
     X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key); 
     RSAPublicKey pbk = (RSAPublicKey) rsaKeyFac.generatePublic(keySpec); 
     System.out.println("MODE:"+Cipher.ENCRYPT_MODE); 
     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
     cipher.init(Cipher.ENCRYPT_MODE, pbk); 

     byte[] encDate = cipher.doFinal(data); 
     return encDate; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

這裏有什麼我想出了在PHP腳本:

use phpseclib\Crypt\RSA as RSA; 




$PUB_KEY = '-----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJ1fKGMV/yOUnY1ysFCk0yPP4bfOolC/nTAyHmoser+1yzeLtyYsfitYonFIsXBKoAYwSAhNE+ZSdXZs4A5zt4EKoU+T3IoByCoKgvpCuOx8rgIAqC3O/95pGb9n6rKHR2sz5EPT0aBUUDAB2FJYjA9Sy+kURxa52EOtRKolSmEwIDAQAB 
-----END PUBLIC KEY-----'; 

$PAYLOAD = 'b78850d2f35108b4bc4e7a41'; 

function encrypt($key,$payload){ 
    $rsa = new RSA(); 
    $rsa->loadKey($key); // public key 

    $rsa->setEncryptionMode(2); 
    $ciphertext = $rsa->encrypt($payload); 

    return base64_encode($ciphertext); 
} 

Java版本使用PKCSPADDING,所以我將phpseclib的模式設置爲2,即PKCSPADDING,但仍然無法工作。我錯過了什麼?任何人都可以爲我指出來嗎?

UPDATE:

不知道這是造成它的原因,但我去掉了 「----- BEGIN PUBLIC KEY -----」 和「----- END PUBLIC KEY ----「部分,它工作。

感謝大家的幫助。

+2

幾乎一切關於這聽起來真的錯了,你可能想使用支付網關重新考慮。 – pvg

+0

我與pvg。刪除這些行不應該有所作爲。我嘗試加載您的密鑰,因爲您發佈它並執行'echo $ rsa'並獲得與您發佈的密鑰相同的密鑰。我也嘗試刪除你說的你刪除的行,並獲得相同的密鑰,當我也這樣做。所以看起來好像刪除這些行就是改變密鑰。 PKCS1填充是隨機的,所以它幾乎可能似乎支付網關只是無法正確容納所有可能的字節,可以隨機選擇.. – neubert

+0

這可能是,我知道網關沒有使用他們的最佳技術結束,但我們沒有任何選擇開始。但無論如何,真的很感謝幫助和反饋! –

回答

1

在開始加密過程之前,請試着做define('CRYPT_RSA_PKCS15_COMPAT', true);

報價phpseclib 2.0的RSA.php:

/** 
* RSAES-PKCS1-V1_5-DECRYPT 
* 
* See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. 
* 
* For compatibility purposes, this function departs slightly from the description given in RFC3447. 
* The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the 
* private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the 
* public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed 
* to be 2 regardless of which key is used. For compatibility purposes, we'll just check to make sure the 
* second byte is 2 or less. If it is, we'll accept the decrypted string as valid. 
* 
* As a consequence of this, a private key encrypted ciphertext produced with \phpseclib\Crypt\RSA may not decrypt 
* with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but 
* not private key encrypted ciphertext's. 
* 
* @access private 
* @param string $c 
* @return string 
*/ 
+0

upvoting你的答案,因爲它可能有助於其他雖然我沒有嘗試這一點。 –