簡體   English   中英

如何在PHP中復制Java加密?

[英]How to replicate Java encryption in PHP?

我正在努力實現的一些背景。

第1部分。

PHP服務器與基於Java的設備通信。 PHP使用OpenSSL生成公鑰/私鑰對,然后將公鑰發送給設備,后者又返回一個加密的macKey (使用公鑰生成),編碼在base64中。 PHP現在需要使用私鑰對macKey解碼進行base64解碼和解密。

PHP中以下Java代碼片段的等價物是什么?

String base64EncodedMacKey = "LkvTT9LFj5lcxRRB8KrwwN906fSIDDcJvQK3E7a5PbR+Ox9WnslOs32jSCC9FkE8ouvr2MfWwtppuZmoPjaxwg3yAQI4UN3T1loISuF2VwKWfJ45fywbK9bNnD5Cw7336mjoGctv77Tg3JXPrsRwgMGIlBsNwdt1B0wgT4MMMAjl32TnBI3iwQ94VTMHffrK+QToddTahRHHoVsr3FVrETdiqKXdkiX1jES53im5lrXYIsY89UFkGzPo+3u4ijKIQWSLvYnA5wXI128gFHKxKYS82MbJDUn9i1RVFsGaP6T3nQRSX5SZNpSe5yGFWwMgYOx0KXMgET82FeaL2hfWuw==";
byte[] base64DecodedMacKey = DatatypeConverter.parseBase64Binary(base64EncodedMacKey);

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, keypair.getPrivate());

byte[] macKey = cipher.doFinal(base64DecodedMacKey);

這是我在PHP中嘗試的內容,但是在解密macKey時我對使用字節數組與字符串感到困惑

$macKey = 'LkvTT9LFj5lcxRRB8KrwwN906fSIDDcJvQK3E7a5PbR+Ox9WnslOs32jSCC9FkE8ouvr2MfWwtppuZmoPjaxwg3yAQI4UN3T1loISuF2VwKWfJ45fywbK9bNnD5Cw7336mjoGctv77Tg3JXPrsRwgMGIlBsNwdt1B0wgT4MMMAjl32TnBI3iwQ94VTMHffrK+QToddTahRHHoVsr3FVrETdiqKXdkiX1jES53im5lrXYIsY89UFkGzPo+3u4ijKIQWSLvYnA5wXI128gFHKxKYS82MbJDUn9i1RVFsGaP6T3nQRSX5SZNpSe5yGFWwMgYOx0KXMgET82FeaL2hfWuw==';
$base64DecodedMacKey = base64_decode($macKey);
openssl_private_decrypt($base64DecodedMacKey, $decrypted, $privateKey);

上面的$decrypted保存了一些二進制數據,所以我不確定是否需要將其轉換為字節數組或將其視為字符串...


第2部分。

每個請求都有一個counter macKey的Java代碼中的macKey用於從counter創建MAC值。

PHP中以下Java代碼片段的等價物是什么?

int counter = 0;
String nextCounter = String.valueOf(++counter);
SecretKeySpec signingKey = new SecretKeySpec(macKey, "AES");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] counterMac = mac.doFinal(nextCounter.getBytes("UTF-8"));
String base64EncodedMac = DatatypeConverter.printBase64Binary(counterMac);

上面的base64EncodedMac最終被發送到設備以驗證通信。

我嘗試使用Google搜索不同的解決方案,但是我沒有成功在PHP中生成有效的base64EncodedMac字符串,以便設備批准它。

自己找到了解決方案。 對於第1部分,我選擇使用phpseclib生成公鑰/私鑰並指定加密算法。 解密macKey

$rsa = new Crypt_RSA();
$keys = $rsa->createKey(2048);
// [...]

$macKey = base64_decode($base64EncodedMacKey);

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->loadKey($keys['privatekey']);
$decryptedMac = $rsa->decrypt($macKey);

其次是第2部分:

$counter = 0;
$hmac = hash_hmac('sha256', ++$counter, $decryptedMac, true);
$counterMac = base64_encode($hmac);

令人困惑的主要部分是在Java中,HMAC是在字節數組之外完成的,而在PHP中, hash_hmac函數需要將String作為其第二個參數,因此使用unpack()是不夠的。 但是,似乎直接通過了$counter 將第4個參數用作TRUE以返回原始數據也很重要。

暫無
暫無

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

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