什么是equivelant openssl命令在Java代码中执行以下操作

问题描述 投票:-2回答:2

嗨,我有以下Java代码。

什么是Openssl命令等效。我希望能够从OS命令行运行。

这就是我认为openssl命令的等价物......但我并不完全确定。

openssl dgst -sha256 -sign my_private.key -out /tmp/sign.sha256 codeTosign.txt

当我尝试两个然后比较它们sign.sha256比较System.out.println的输出(“Signature =”+ base64Signature);

他们不相等/不匹配。

import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class SHA256RSA {

public static void main(String[] args) throws Exception {
    String input = "sample input";

    // Not a real private key! Replace with your private key!
    String strPk = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9"
            + "w0BAQEFAASCBKkwggSlAgEAAoIBAQDJUGqaRB11KjxQ\nKHDeG"
            + "........................................................"
            + "Ldt0hAPNl4QKYWCfJm\nNf7Afqaa/RZq0+y/36v83NGENQ==\n" 
            + "-----END PRIVATE KEY-----\n";

    String base64Signature = signSHA256RSA(input,strPk);
    System.out.println("Signature="+base64Signature);
}

// Create base64 encoded signature using SHA256/RSA.
private static String signSHA256RSA(String input, String strPk) throws Exception {
    // Remove markers and new line characters in private key
    String realPK = strPk.replaceAll("-----END PRIVATE KEY-----", "")
                         .replaceAll("-----BEGIN PRIVATE KEY-----", "")
                         .replaceAll("\n", "");

    byte[] b1 = Base64.getDecoder().decode(realPK);
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
    KeyFactory kf = KeyFactory.getInstance("RSA");

    Signature privateSignature = Signature.getInstance("SHA256withRSA");
    privateSignature.initSign(kf.generatePrivate(spec));
    privateSignature.update(input.getBytes("UTF-8"));
    byte[] s = privateSignature.sign();
    return Base64.getEncoder().encodeToString(s);
}

参考:https://www.quickprogrammingtips.com/java/how-to-create-sha256-rsa-signature-using-java.html

java openssl
2个回答
0
投票

除了输入的差异(内存变量与文件内容,我假设你完全相同),你的Java代码base64编码结果(并在前面粘贴Signature=),但openssl dgst -sign没有。

最简单的方法是让Java编写二进制文件(不编码),但是你必须用二进制进行比较,例如Unix上的cmp或Windows上的fc /b;视觉或文本模式比较不会给出可靠的结果。

您可以改为对OpenSSL输出进行base64编码,但要小心:有许多base64编码方案,它们通常会产生相似但不相同的输出,因此即使签名相同,输出也可能不相等(见下文)。特别是如果Base64是Java8 + java.util.Base64,那么默认的“基本”编码器使用经典的PEM / MIME字母表而不使用行终止符。如果将openssl dgst -sign的输出传输到openssl base64,则默认为相同的字母,但每64个字符行终止符。如果你使用openssl base64 -A它应该抑制行终止符。如果您的系统上有其他base64编码程序,则它们(每个)的行为可能不同。如果你真的想在前面使用Signature=,可以使用任何适当的文本操作程序,如sed awk perl,甚至是Unix上的大多数shell。

除此之外:您不应该假设您可以通过将签名与新生成的签名进行比较来验证签名。这里使用的方案,RSASSA-PKCS1-v1_5又称“经典类型01”,恰好是确定性的,并且比较恰好起作用,但许多其他数字签名方案不是确定性的。验证签名的正确方法是应用签名方案定义的验证过程。例如,Java Signature.initVerify(pubkeyobj), update(databuf), verify(signaturebuf)或OpenSSL命令行dgst -$hash <datafile -verify pubkeyfile -signature file


0
投票

谢谢大家的帮助。我最终遇到的最终问题是当我复制粘贴的字符串“sample input”时,它附加了一个“\ n”。当这被删除。 openssl命令的输出与java片段的输出相匹配。

谢谢大家。

© www.soinside.com 2019 - 2024. All rights reserved.