当前位置: 首页 > 知识库问答 >
问题:

Java生成的数字签名不会在openssl中验证

薛华奥
2023-03-14

我正在用Java对一个二进制文件进行签名。我能够在Java代码中签名和验证,但是在openssl中使用生成的签名时,它无法验证到相同的二进制文件。步骤是:加载数据-

这应该相当于在openssl: openssl dgst-sha256-符号private.key-二进制target.bin

我验证了sha256与openssl生成的匹配。

public class Main {

    public static void main(final String[] args) {
        Signature signer;
        KeyStore ks;
        byte[] signature;
        PrivateKey privateKey;
        PublicKey publicKey;
        String alias = "ctest3";
        String sigfile = "c:\\temp\\signature";
        String datafile = "c:\\temp\\data.bin";

        try {
            ks = KeyStore.getInstance("ncipher.sworld", "nCipherKM");
            FileInputStream in = new FileInputStream("C:\\private\\ctest3.ncsw");
            ks.load(in, null);
        } catch (KeyStoreException |
                NoSuchAlgorithmException |
                CertificateException |
                IOException |
                NoSuchProviderException e) {
            System.err.println(e.getMessage());
            return;
        }

        try {
            privateKey = (PrivateKey) ks.getKey(alias, null);
            Certificate cert = ks.getCertificate(alias);
            publicKey = cert.getPublicKey();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }

        byte[] payload;
        try {
            payload = Files.readAllBytes(Paths.get(datafile));
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return;
        }

        byte[] spayload = sha256(payload, false);
        if (spayload == null) {
            return;
        }

        try {
            signer = Signature.getInstance("SHA256withECDSA");
            signer.initSign(privateKey);
            signer.update(spayload);
            signature = signer.sign();
        } catch (NoSuchAlgorithmException | SecurityException | SignatureException | InvalidKeyException e) {
            System.out.println(e.getMessage());
            return;
        }

        writeBytesToFile(signature, sigfile);
        KeyPair kp = new KeyPair(publicKey, privateKey);

        if (Verify(datafile, sigfile, kp)) {
            System.out.println("success");
        }
    }

    private static byte[] sha256(byte[] data) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-256");
            byte[] mDigest = digest.digest(data);
            return mDigest;
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

    private static boolean Verify(String filename, String signaturePath, KeyPair kp) {
        Signature verify;
        byte[] dataRaw;
        byte[] signature;
        byte[] data;

        try {
            dataRaw = Files.readAllBytes(Paths.get(filename));
            signature = Files.readAllBytes(Paths.get(signaturePath));
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return false;
        }

        data = sha256(dataRaw, false);
        if (data == null)
            return false;

        try {
            verify = Signature.getInstance("SHA256withECDSA");
            PublicKey pub = kp.getPublic();
            verify.initVerify(pub);
            verify.update(data);
            if (verify.verify(signature))
                return true;
        } catch (NoSuchAlgorithmException | SecurityException | SignatureException | InvalidKeyException e) {
            System.out.println(e.getMessage());
            return false;
        }

        return false;
    }

    private static void writeBytesToFile(byte[] bFile, String fileDest) {
        try (FileOutputStream fileOuputStream = new FileOutputStream(fileDest)) {
            fileOuputStream.write(bFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

共有1个答案

邹宏峻
2023-03-14

事实证明,当Signature对象使用SHA256和ECDSA密钥启动时,它本身将在Sign()调用期间生成SHA256哈希。删除上面代码中对sha256()的调用将使用OpenSSL进行验证。

 类似资料:
  • 我正在尝试从文件中生成签名,以便客户端使用OpenSSL验证它们,因此使用Bouncy Castle在Java中实现相应的OpenSSL命令: 使用bouncy Castle1.57和java,我们从文件中获得字节数组签名,我可以在代码中验证它。Private,public和certificate是从OpenSSL生成的。 另一方面,openSSL总是通过验证从代码生成的签名而导致“验证失败”。

  • 我需要用c语言验证由JAVA签名API生成的签名。我有一套相同的公钥和私钥。我还验证了c语言的签名和验证工作。但是我在验证JAVA生成的签名时遇到了问题。我看了所有的文件,尝试了不同的方法,但我似乎还是不明白。我将使用用于验证的原始JAVA代码粘贴等效的c代码。 原始JAVA代码: C代码: 我有3个问题: 这是验证签名的正确方法吗? 我需要在验证数据之前对其进行散列吗?如果是,那么JAVA在签名

  • 我正在编写一些代码,试图对一些数据进行签名。在将openssl生成的私钥转换为Java密钥库之后,我将Java签名类与SHA256withRSA一起使用。我试图确认openssl中Java类返回的签名,但由于某些原因,我无法让openssl进行验证。我最终需要在iOS Swift 3中实现这个签名验证,但在找到库之前,我想尝试根据openssl标准检查Java签名。 例如,我从我们的登录服务器得到

  • 问题内容: 我试图让Java验证签名的SHA-1哈希,但是它一直返回false。我在Go中有以下代码,该代码生成RSA密钥对并签名并返回击中/ sign端点的任何消息,以及十六进制编码的哈希,公钥模数和指数: 在Java / Android方面,我有以下代码,该代码在发送相关位后会使用未解析的JSON对象击中此函数,但是一旦到达签名验证部分,它始终会返回false: 问题答案: 在Java中,您无

  • 最近我需要在Java中使用RSA对一个字符串进行签名,并在C++中验证签名。 在Java,现在我认为一切都是好的,我创建了public.keystore和private.keysore,可以成功地对数据进行签名和veify。但是当我试图用C++验证它时,它显示签名失败。 这是我的Java代码,在Java,我将数据签名到base64String,并将其保存在我的本地文件中,保存为“sig.dat”,

  • 情况是我必须检查一个数字签名: 字符串1“A1005056807CE11EE2B4CE0025305725CFRCN=KED,OU=I0020266601,OU=SAPWebAS,O=SAPTrustCommunity,C=DE20130611102236”通过PKCS#7签名并通过HTTP-URL发送给我。 我在BASE64中获得签名的内容(在代码字符串sc中查找)。 现在我必须检查,如果Str