如何在PHP中复制Java加密?

时间:2016-07-03 14:35:19

标签: java php encryption

我想要完成的一些背景。

第1部分。

PHP服务器与基于Java的设备通信。 PHP使用OpenSSL生成公钥/私钥对,然后将公钥发送给设备,后者又返回一个加密的class MyTextLayer : CALayer { @NSCopying var string : NSAttributedString? override func drawInContext(ctx: CGContext) { super.drawInContext(ctx) UIGraphicsPushContext(ctx) string?.drawWithRect(self.bounds, options: .UsesLineFragmentOrigin, context: nil) UIGraphicsPopContext() } } (使用公钥生成),以base64编码。 PHP现在需要使用私钥对macKey进行base64解码和解密。

PHP中以下Java代码段的等效内容是什么?

macKey

这是我在PHP中尝试的内容,但是在解密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); 时,我对使用字节数组与字符串感到困惑

macKey

上面的$macKey = 'LkvTT9LFj5lcxRRB8KrwwN906fSIDDcJvQK3E7a5PbR+Ox9WnslOs32jSCC9FkE8ouvr2MfWwtppuZmoPjaxwg3yAQI4UN3T1loISuF2VwKWfJ45fywbK9bNnD5Cw7336mjoGctv77Tg3JXPrsRwgMGIlBsNwdt1B0wgT4MMMAjl32TnBI3iwQ94VTMHffrK+QToddTahRHHoVsr3FVrETdiqKXdkiX1jES53im5lrXYIsY89UFkGzPo+3u4ijKIQWSLvYnA5wXI128gFHKxKYS82MbJDUn9i1RVFsGaP6T3nQRSX5SZNpSe5yGFWwMgYOx0KXMgET82FeaL2hfWuw=='; $base64DecodedMacKey = base64_decode($macKey); openssl_private_decrypt($base64DecodedMacKey, $decrypted, $privateKey); 保存了一些二进制数据,因此我不确定是否需要将其转换为字节数组或将其视为字符串...

第2部分。

每个请求都有一个$decrypted。上面的Java代码中的counter用于创建macKey之外的MAC值。

PHP中以下Java代码段的等效内容是什么?

counter

上面的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); 最终被发送到设备以验证通信。

我尝试使用Google搜索不同的解决方案,但是我还没有成功在PHP中生成有效的base64EncodedMac字符串,以便设备批准它。

1 个答案:

答案 0 :(得分:0)

自己找到解决方案。对于第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来返回原始数据也很重要。