【发布时间】:2014-03-18 13:24:49
【问题描述】:
我目前被分配了验证使用 openssl 生成的数字签名的任务,我收到的文件基本上是两个文件,一个是 xml 数据,另一个是该 xml 数据的相应签名,用于签署数据的密钥是具有 SHA1 算法的 RSA,使用的 openssl 命令是: openssl smime -sign -binary -in {datafile} -out {signaturefile} -outform der -inkey {privatekey} -signer {publickey} 其中 {datafile} = CSV 或 XML 格式的输入文件,包含要签名的数据 {signaturefile} = 仅包含 PKCS#7 格式的数字签名的输出文件,文件名与 datafile 相同,但扩展名为 .sig { privatekey} = 用于签名的密钥的私钥部分 {publickey} = 用于签名的密钥的公钥部分,我写了一个类来验证这些文件,但结果总是返回一个错误的意思验证失败。下面是我写的代码:有人可以帮我看看如何使用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 ;
}
【问题讨论】:
-
您是否尝试过使用硬编码值作为输入来查看代码是否在没有任何动态交互的情况下提供了预期的输出?尝试将验证变量中的值复制到 Notepad++ 之类的东西,并启用查看所有字符的选项,您可能会看到一些不应该存在的有趣元素(只是一个疯狂的猜测)。您是否尝试过在
sig.verify(sigToVerify)处反编译/检查此方法的源代码以查看其工作原理? -
你如何获得 java 使用的签名方法的来源?我能够使用 openssl 验证签名,但这是一种实际进行验证的粗略方式,当我通过 openssl 查看 der 格式的签名时,签名值的字节加起来不等于 256。
-
签名文件不仅仅是嵌入在其中的签名,因为通常签名应该是几行,但这个文件看起来有更多内容,所以我尝试使用偏移量来获取最后的 256字节,因为那是签名所在的位置,但我仍然得到错误的返回
-
所以,一个快速的脏方法是通过命令行(嗯,你可以通过 Java 代码调用 CLI 操作......只是说')。关于源码问题,你得找到这个类所在的jar文件(cua.li/Alain-Bearez.html),找到后可以用反编译器看一下:jd.benow.ca
-
目前我所做的是我编写了代码来调用验证命令作为系统调用,我使用 if 语句来读取输出并确定签名是否成功,然后我将代码用作我的 Talend 工作中的一个库,但正如你所说,这是一种肮脏的方式,我必须下载反编译器吗?
标签: java