[英]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.