为什么我用OpenSSL和Java生成的RSA-SHA256签名不同?

我想用Java生成RSA-SHA256签名,但无法在控制台上生成与OpenSSL相同的签名。


这是我对OpenSSL所做的工作(在本教程之后):


生成密钥对:


openssl genrsa -out private.pem 1024

提取公钥:


openssl rsa -in private.pem -out public.pem -outform PEM -pubout

创建数据哈希:


echo 'data to sign' > data.txt

openssl dgst -sha256 < data.txt > hash

生成的哈希文件从(stdin)=我手动删除的文件开始(首先忘了提起它,谢谢mata)。


签名哈希:


openssl rsautl -sign -inkey private.pem -keyform PEM -in hash  > signature

为了在Java中重现结果,我首先将私钥从PEM转换为DER:


openssl pkcs8 -topk8 -inform PEM -outform DER -in private.pem -nocrypt > private.der

现在,我编写了这个Java类来生成相同的签名:


public class RSATest {


    public static void main(String[] args) throws IOException,

            NoSuchAlgorithmException, InvalidKeySpecException,

            InvalidKeyException, SignatureException {


        byte[] encodedPrivateKey = readFile("private.der");

        byte[] content = readFile("data.txt");


        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);

        RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory

                .generatePrivate(keySpec);


        Signature signature = Signature.getInstance("SHA256withRSA");

        signature.initSign(privateKey);

        signature.update(content);

        byte[] signatureBytes = signature.sign();


        FileOutputStream fos = new FileOutputStream("signature-java");

        fos.write(signatureBytes);

        fos.close();

    }


    private static byte[] readFile(String filename) throws IOException {

        File file = new File(filename);

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(

                file));

        byte[] bytes = new byte[(int) file.length()];

        bis.read(bytes);

        bis.close();

        return bytes;

    }


}

不幸的是结果并不相同,所以我想我一定做错了什么,但我不知道该怎么办。你们中的某人可以帮助我找到错误吗?




子衿沉夜
浏览 312回答 3
3回答

梵蒂冈之花

在第一种情况下,您采用任意摘要并对其进行签名,在此过程中将丢失使用sha256创建的摘要的信息,因此生成的签名将不/不能包含该信息,而第二种情况下的ASN1数据签名表明确实如此。因此,只有在验证者确切知道摘要是如何产生的情况下,才可以验证第一个签名,因此它不是真正无效,而是不完整(较低级别)的输出。

海绵宝宝撒

你又是对的。使用您的命令,签名与Java生成的签名相同。但是另一个问题出现在我身上。我的旧(不正确)签名已使用命令成功验证,该命令openssl rsautl -verify -inkey public.pem -keyform PEM -pubin -in signature > verified不再起作用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java