Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 验证使用openssl生成的分离xml签名_Java - Fatal编程技术网

Java 验证使用openssl生成的分离xml签名

Java 验证使用openssl生成的分离xml签名,java,Java,我目前被分配任务验证使用openssl生成的数字签名,我收到的文件基本上是两个文件,一个是xml数据,另一个是该xml数据的相应签名,用于签名数据的密钥是RSA,算法为SHA1,使用的openssl命令是:openssl smime-sign-binary-in{datafile}-out{signaturefile}-outform der-inkey{privatekey}-signer{publickey} 其中{datafile}=输入文件,CSV或XML格式,包含要签名的数据{sign

我目前被分配任务验证使用openssl生成的数字签名,我收到的文件基本上是两个文件,一个是xml数据,另一个是该xml数据的相应签名,用于签名数据的密钥是RSA,算法为SHA1,使用的openssl命令是:openssl smime-sign-binary-in{datafile}-out{signaturefile}-outform der-inkey{privatekey}-signer{publickey} 其中{datafile}=输入文件,CSV或XML格式,包含要签名的数据{signaturefile}=输出文件,仅包含PKCS#7格式的数字签名,文件名与数据文件相同,但扩展名为.sig{privatekey}=用于签名{publickey}的密钥的私钥部分=用于签名的密钥的公钥部分,我编写了一个类来验证这些文件,但结果总是返回一个false,表示验证失败。下面是我编写的代码:有人能帮助我如何使用java验证openssl分离签名吗

public PublicKey pubTest(String path) throws Exception
 {
     FileInputStream fin = new FileInputStream(path);
     CertificateFactory f = CertificateFactory.getInstance("X.509");
     X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
     PublicKey pk = certificate.getPublicKey();
     System.out.println(pk);
     return pk;
 }
 public byte[] signature(String sigPath) throws Exception
 {
     FileInputStream sigfis = new FileInputStream(sigPath);
     byte[] sigToVerify = new byte[sigfis.available()]; 
     sigfis.read(sigToVerify);
     sigfis.close();
     System.out.println(sigToVerify.length);

     return sigToVerify ;
 }

 public boolean verification(PublicKey pubKey , String dataPath , byte[] sigToVerify ) throws Exception, NoSuchProviderException ,SignatureException
{

    Signature sig = Signature.getInstance("SHA1withRSA");
    sig.initVerify(pubKey);
    FileInputStream datafis = new FileInputStream(dataPath);
    BufferedInputStream bufin = new BufferedInputStream(datafis);
    byte[] buffer = new byte[1024];
    int len;
    while (bufin.available() != 0)
    {
        len = bufin.read(buffer);
      sig.update(buffer, 0, len);
    }
    System.out.println(buffer.length);
    bufin.close();
    boolean verifies = sig.verify(sigToVerify);
    System.out.println("signature verifies: " + verifies);
    return verifies ;
}

现在很晚了,但如果有人遇到:

openssl smime-sign
默认情况下会生成一个“间接”分离签名,即不包含encapContentInfo中的数据但使用SignedAttr的签名。见5.3至5.6;您需要将数据的散列与SignedAttr中的message digest属性进行比较,然后根据SignedAttr验证签名(隐式标记恢复为basic)


标准Java crypto(目前?)不支持CMS/PKCS#7,但BouncyCastle可以选择这样做。考虑,

是否尝试使用硬编码的值作为输入,看看代码是否提供了预期的输出而没有任何动态交互?尝试将验证变量中的值复制到类似Notepad++的地方,并启用该选项以查看所有字符,您可能会看到一些不应该存在的有趣元素(只是一个猜测)。您是否尝试在此处反编译/检查此方法的源代码
sig.verify(sigtovify)
以了解其工作原理?如何获取java使用的签名方法的源代码?我能够使用openssl验证签名,但这是一种实际进行验证的粗糙方法,当我通过openssl查看der格式的签名时,签名值的字节数加起来不等于256。签名文件中嵌入的不仅仅是签名,因为通常签名应该只有几行,但该文件看起来更多,因此我尝试使用偏移量来获取最后256个字节,因为签名就在这里,但我仍然得到假返回值。因此,一种快速的方法是通过命令行(好的,您可以通过Java代码调用CLI操作……只需sayin)。关于源代码问题,您必须找到存储此类的jar文件(),一旦找到它,您可以使用反编译器来查看:目前我所做的是编写代码,将验证命令作为系统调用调用,并使用if语句读取输出并确定签名是否成功,然后在我的Talend作业中将代码用作lib,但正如您所说,这是一种肮脏的方式,我必须下载反编译器吗?