如何使用openssl模拟Java Signature签名方法?

时间:2012-04-13 01:23:43

标签: java cryptography openssl

我正在使用一台服务器,该服务器要求部分登录URL包含身份验证。该方案的工作方式(如手册中所推荐的)是

  • 使用Java JDK keytool(在Java密钥库中创建它们)生成公钥/私钥对
  • 使用Java JDK keytool为密钥对生成证书
  • 证书已安装在服务器上。

登录客户端时(我的代码)

  • 生成明文标记字符串
  • 使用SHA1和DSA
  • 使用私钥对明文标记字符串进行签名
  • 在登录网址中包含已签名的令牌字符串。

Java keytool不提供从密钥库导出私钥的机制,但是我单独使用Java代码从密钥库中提取私钥并将其保存在文件中 - 基于How do I list / export private keys from a keystore?。 / p>

当客户端使用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 Signature签名方法?

1 个答案:

答案 0 :(得分:2)

另一个帖子是红鲱鱼。 DSA的工作方式与RSA不同,不使用MessageDigest前缀。

但是openssl dgst -dss1应该直接起作用(包括SHA1摘要)。

你试过这个吗?

echo -n $tokenString |
  openssl dgst -dss1 -passin pass:$storePassword -sign $privateKeyFile > tokensigned