如何使用openssl来模拟Java签名方法?
问题描述:
我正在使用一个服务器,要求登录URL的一部分包含认证。该方案的工作(如手册推荐)的方式是如何使用openssl来模拟Java签名方法?
- 公钥/私钥对使用
- 一个证书生成的Java JDK密钥工具(这将创建他们在一个Java密钥库)生成密钥对使用Java JDK keytool
- 证书安装在服务器上。
当客户端在登录(我的代码)
- 产生一个明文的令牌字符串
- 迹象明文的令牌字符串使用私钥使用SHA1和DSA
- 包括签名令牌字符串在登录URL中。
Java的密钥工具不提供一种机制来从导出密钥库中的私有密钥,但分开我的Java代码来提取密钥库中的私有密钥并将其保存在一个文件 - 基于How do I list/export private keys from a keystore?。
这一切都适用于客户端使用Java进行签名,代码如下所示。
String plaintext = "This is a sample plaintext token string";
Signature instance = Signature.getInstance("SHA1withDSA");
instance.initSign(privateKey);
instance.update((plaintext).getBytes());
byte[] signature = instance.sign();
它也适用于客户端使用PHP执行签名,代码如下所示。这里的私有密钥从PHP中的Java密钥库文件中检索]
$privateKey = openssl_pkey_get_private("file://$keyfile", $keystorePassword);
openssl_sign($paramsEncoded, $signature, $privateKey, OPENSSL_ALGO_DSS1))
不过,我现在有一个顾客想要构建使用bash脚本和OpenSSL登录URL的情况 - 那是行不通的。我的最新版本的代码如下所示,它执行SHA1消息摘要,然后是DSA标志。但服务器拒绝令牌。
echo $tokenString | openssl dgst -sha1 > tokendigest
openssl dgst -dss1 -passin pass:$storePassword -sign $privateKeyFile > tokensigned
我碰到这个职位(Using SHA1 and RSA with java.security.Signature vs. MessageDigest and Cipher),这意味着Java签名标志方法不签字的摘要,而是标志摘要算法ID和摘要的级联。在逐步完成帖子中的代码之后,看起来(对于SHA1)摘要需要以字节48 33 48 9 6 5 43 14 3 2 26 5 0 4 20
作为前缀。但即使在添加之后,仍然无法让opensll生成服务器可以接受的签名标记。
有谁知道如何使用openssl来模拟Java签名方法吗?
答
另一篇文章是红鲱鱼。 DSA的工作方式与RSA不同,不使用MessageDigest前缀。
但openssl dgst -dss1
应该直接工作(它包括SHA1消化)。
你试过这个吗?
echo -n $tokenString |
openssl dgst -dss1 -passin pass:$storePassword -sign $privateKeyFile > tokensigned
我只是试着用相同的“令牌登录错误”结果。我甚至添加了一个openssl验证(如下所示) - openssl在其中报告了验证正常。 'echo $ tokenString | openssl dgst -dss1 -passpass pass:$ storePassword -sign $ privateKeyFile> $ signedTokenOpensslFile echo $ tokenString | openssl dgst -dss1 -verify $ publicKeyFile -signature $ signedTokenOpensslFile' – Torid 2012-04-13 17:58:37
@Torid:您的问题可能是'echo'添加到字符串中的额外新行。试试'echo -n'。 – 2012-04-13 18:33:58
是的。 'echo -n'固定它。我喜欢stackoverflow.com - 即使它让我感觉有点愚蠢。谢谢! – Torid 2012-04-13 19:05:45