如何在PHP中复制Java加密?

如何在PHP中复制Java加密?,java,php,encryption,Java,Php,Encryption,一些我正在努力完成的背景 第一部分 PHP服务器与基于Java的设备通信。PHP使用OpenSSL生成一个公钥/私钥对,然后将公钥发送到设备,然后设备返回一个加密的macKey(使用公钥生成),用base64编码。PHP现在需要使用私钥对macKey进行base64解码和解密 下面的Java代码片段在PHP中的等价物是什么 int counter = 0; String nextCounter = String.valueOf(++counter); SecretKeySpec signingK

一些我正在努力完成的背景

第一部分

PHP服务器与基于Java的设备通信。PHP使用OpenSSL生成一个公钥/私钥对,然后将公钥发送到设备,然后设备返回一个加密的
macKey
(使用公钥生成),用base64编码。PHP现在需要使用私钥对
macKey
进行base64解码和解密

下面的Java代码片段在PHP中的等价物是什么

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);
String base64EncodedMacKey=(2)一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,两个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个hfwuw==”;
字节[]base64DecodedMacKey=DatatypeConverter.parseBase64Binary(base64EncodedMacKey);
Cipher Cipher=Cipher.getInstance(“RSA/ECB/PKCS1Padding”);
cipher.init(cipher.DECRYPT_模式,keypair.getPrivate());
字节[]macKey=cipher.doFinal(base64DecodedMacKey);
下面是我在PHP中尝试的内容,但是在解密
macKey

(代码)麦基(代码)的意思是(代码)的意思是(代码)的意思是(代码)的意思意思是(代码)的意思意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是,他们的意思是他们的意思是,他们的意思是他们的意思是他们的意思是,他们的意思是他们的意思是他们的意思是,他们的意思是他们的意思是,他们的意思是他们的意思是他们的意思是他们的意思是他们的意思是他们的意思是他们的意思是,他们的意思是他们的意思是他们的意思是他们的意思是他们的意思是他们的意思是他们的意思是他们的0KxMget82FeaL2hfWuw=='; $base64DecodedMacKey=base64_decode($macKey); openssl_private_decrypt($base64DecodedMacKey,$decrypted,$privateKey); 上面的
$decrypted
保存一些二进制数据,因此我不确定是否需要将其转换为字节数组或将其视为字符串


第二部分

每个请求都有一个
计数器
。上面Java代码中的
macKey
用于从
计数器
中创建MAC值

下面的Java代码片段在PHP中的等价物是什么

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
最终发送到设备以验证通信


我尝试过用谷歌搜索不同的解决方案,但是我没有成功地在PHP中生成一个有效的
base64EncodedMac
字符串供设备批准。

自己找到了解决方案。在第1部分中,我选择使用来生成公钥/私钥并指定加密算法。解密
macKey

$rsa=new Crypt_rsa();
$keys=$rsa->createKey(2048);
// [...]
$macKey=base64_解码($base64EncodedMacKey);
$rsa->setEncryptionMode(CRYPT\u rsa\u ENCRYPTION\u PKCS1);
$rsa->loadKey($key['privatekey']);
$decryptedMac=$rsa->decrypt($macKey);
第二部分:

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

最令人困惑的是,在Java中,HMAC是在字节数组之外完成的,而在PHP中,
hash_HMAC
函数需要一个字符串作为其第二个参数,因此使用
unpack()
是不够的。但是,它似乎可以直接传递
$计数器
。使用第四个参数作为
TRUE
返回原始数据也很重要。

自己找到了解决方案。对于第1部分,我选择使用来生成公钥/私钥并指定加密算法。解密麦基:

$rsa=new Crypt_rsa();
$keys=$rsa->createKey(2048);
// [...]
$macKey=base64_解码($base64EncodedMacKey);
$rsa->setEncryptionMode(CRYPT\u rsa\u ENCRYPTION\u PKCS1);
$rsa->loadKey($key['privatekey']);
$decryptedMac=$rsa->decrypt($macKey);
第二部分:

$counter=0;
$hmac=hash_hmac('sha256',+$counter,$decryptedMac,true);
$counterMac=base64_编码($hmac);
最令人困惑的是,在Java中,HMAC是在字节数组之外完成的,而在PHP中,
hash_HMAC
函数需要一个字符串作为其第二个参数,因此使用
unpack()
不够。但是,它似乎可以直接传递
$计数器
。使用第四个参数作为
TRUE
返回原始数据也很重要