我想要完成的一些背景。
第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
字符串,以便设备批准它。
答案 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
来返回原始数据也很重要。