【发布时间】:2012-04-25 10:06:34
【问题描述】:
我正在使用的服务器要求登录 URL 的一部分包括身份验证。该方案的工作方式(如手册中推荐的那样)是
- 使用 Java JDK keytool 生成公钥/私钥对(在 Java 密钥库中创建它们)
- 使用 Java JDK keytool 为密钥对生成证书
- 证书已安装在服务器上。
登录客户端时(我的代码)
- 生成明文令牌字符串
- 使用 SHA1 和 DSA 使用私钥对明文令牌字符串进行签名
- 在登录 URL 中包含签名的令牌字符串。
Java keytool 不提供从密钥库中导出私钥的机制,但另外我有 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 Signature签名方法吗?
【问题讨论】:
标签: java cryptography openssl