【发布时间】:2016-02-10 11:58:29
【问题描述】:
我看过很多关于如何在 PHP 中创建 HMAC 的帖子,但使用的秘密始终是一个简单的字符串(例如“秘密”)。我需要做的是创建一个 HMAC,其秘密是私钥,例如从包含 PEM 格式私钥的文件中加载。我一直无法找到任何关于这在 PHP(使用 hash_hmac)中是否可行的信息。
用法
使用私钥的 HmacSHA256 签名是在 Java 中创建的,我想使用从文件加载的相同私钥在 PHP 中重新创建此签名(根据我的理解,使用带有 sha256 散列算法的 hash_hmac)。
澄清: 在这种情况下,私钥用作共享密钥,这意味着双方拥有密钥。消息验证过程包括发送带有消息的 HMAC,使用私钥计算,而接收者使用相同的私钥计算 HMAC,并根据发送的签名验证它。
代码
Java:
byte[] data = getDataForSignature();
PrivateKey key = getPrivateKey(); // loaded from a file
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
byte[] hmac = mac.doFinal(data);
// compare hmac with received signature bytes
PHP:
$key = openssl_pkey_get_private("private.key");
$sig = hash_hmac("sha256", $data, $key??, true);
示例私钥
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCSWro05ZKVGxMTCqAyNZRAXp8Gd7wf6vywXRsFckm9MHOAWZL0
SvFAhM6tlCthuPkQb0c+Hx9PWH1+4sW2u3O+VDvjQEB0ZILd79LraBEshK/36Oux
yyw2K+ghk9Yh00nJOzkkonmdZmVxr0AAzw5el2h9yDjlUa1E8BH/1LzBBwIDAQAB
AoGANtwXbHiZh5bMgZi8D9YRqkdNqOj89aHp8loUJOiAR5B/2x64fSYSZLLjniEq
WckyYzyzIdActmtfL07l+ecuLRipsHoHuzjPiiRRnzJQbgBstnB8rHkuN275YSbC
3gE7nyyX0JPEviwqHv++Uig0RCD1ZbrG0SBMKBlGVrFMddECQQDmVguRhRScTJHH
RaXY/zjZtHp0L1dtzzSLM75+ji2UoRy1yK9z+rnE1PM5QC8PQixbwocGwpRIwGQn
hIg1YAM9AkEAoqk+VNbJ9ykoP9r+8o1PrPR1Ff+EIhpTthRyFngHNbNnOFB0D314
+V4wyO+a/gbiIAmvTuOXV/GwOlgnfVDJkwJBAJNHd5QvxPL/3sLNXPN4ljBWP2pl
DwFO2Wkcx/SCEtETh5kQ3mdJbVlXVMJJsQ2PoW923gHLjydJpYDDNJj0cH0CQQCW
8txHOvQ+C9GwQHirenvgExO9EFv8kdXxeNPPCiAWs6AsYGz0Gwpyz/gR4FlDN/wM
ozAu04IVONLDsh8jah9FAkEAsSUvlo7Nh1ITd75kUsStv7Tjxma3SuKViewWCprD
olDNtncfcZC5SrilHAJEabVxGy1fJL3hYvTYfqNkeB1TcA==
-----END RSA PRIVATE KEY-----
【问题讨论】:
-
Java 代码中的
key.getClass().getName()得到了什么?PrivateKey只是其下特定类的父级。您也可以显示示例密钥文件吗?在这种情况下,getPrivateKey似乎是一个重要的功能。 -
@MaartenBodewes 这是一个 sun.security.rsa.RSAPrivateCrtKeyImpl,我还添加了一个示例密钥
-
嗯,Java 只使用
byte[] secret = key.getEncoded();作为键(谁会有 thunk :))。因此,您使用内部 PKCS#8 编码作为密钥。这当然不是一个好习惯,但是如果您可以在 PHP 中使用 binary DER 编码对密钥进行编码,那么您将是黄金。 -
我对你最后的评论只了解一点,我想知道那里到底有什么不好的做法,关于使用二进制 DER 编码的第二部分是什么,但是周五晚上我是累了。
-
对 MAC 使用 RSA 公钥更糟糕;您会期望 RSA 公钥是公开的。你当然不应该将它用于 MAC,它根本没有意义。
标签: java php hash signature hmac