【问题标题】:how to specify signature length for java.security.Signature sign method如何为 java.security.Signature 签名方法指定签名长度
【发布时间】:2018-06-19 01:19:02
【问题描述】:

对于我的应用程序,我正在尝试使用 java.security.Signature 类对一些字节内容进行签名。我遇到的问题是签名永远不会以固定长度生成。例如,有时它以 135、136 或 137 字节的长度生成。有没有办法在最后指定长度或一些填充?任何其他想法或 cmets 表示赞赏。

    private byte[] ecdsaSign(ECPrivateKey key, byte[] content) throws Exception {
                Signature ecdsaSign = Signature.getInstance("SHA256withECDSA", "SC");
                ecdsaSign.initSign(key);
                ecdsaSign.update(content);
                byte[] signature = ecdsaSign.sign();
                return signature;
}

【问题讨论】:

    标签: java security signature sha256


    【解决方案1】:

    对于 ECDSAJava 加密使用由 X9.62、SEC1 和 rfc 3279 sec 2.2.3 标准化的 ASN.1 DER 编码长度略有不同强>。这在另一个 Stack 中有更详细的介绍:https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-ASN.1https://crypto.stackexchange.com/questions/33095/shouldnt-a-signature-using-ecdsa-be-exactly-96-bytes-not-102-or-103https://crypto.stackexchange.com/questions/37528/why-do-openssl-elliptic-curve-digital-signatures-differ-by-one-byte

    这也适用于 DSA,但不适用于 RSA,其中签名(以及密码,因为 RSA 支持签名和加密)对于给定密钥是固定长度的,如 PKCS1 中的 I2OS 和 OS2I 所定义。

    如果您想要不同的编码,例如 PKCS11 使用的固定长度编码(并且您的提供程序名称“SC”暗示了这种可能性),您必须对其进行转换。

    2019-10 年添加:您不再需要在 Java 中自己动手; BouncyCastle 自 1.61 (2019-02) 正确 支持这一点,Java 9 up (2018-12) 中的 SunEC 也是如此。稍后见近乎欺骗Java ECDSAwithSHA256 signature with inconsistent length

    【讨论】:

    • 感谢您的回复。非常感谢。我正在遵循类似的方法,例如stackoverflow.com/questions/39385718/…。在编码为 ASN1 后,我可以获得固定长度的 R 和 S 值,但这给了我两个值。有没有办法将这两个值编码成一个固定长度的序列,比如 base64 或其他格式?
    • @JoelPou:如果您需要与任何其他程序或系统互操作,您需要使用与其兼容的格式,否则您可以使用任何您喜欢的格式正确地保留了 r 和 s 的值。 PKCS11 方法是一种方法,但可能还有成百上千的其他可能性。 Base64 本身不是一种格式,它是一种可以应用于任何格式的编码。例如,XMLDSIG 使用连接固定长度 r 和 s 的 base64。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2020-04-19
    • 2016-01-02
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多