【发布时间】:2014-10-28 11:37:23
【问题描述】:
我的应用程序正在使用 java 安全 API 对文件进行签名和验证。 签名时,我使用 PFX 文件和密码作为输入,签名后我使用字节生成签名文件。 在验证过程中,我使用签名文件、证书文件和签名文件作为输入。 请在下面找到我在验证中使用的代码:
// KeyFilePath= path of certificate file
// fileToVerify = path of signed file
// signatureFilePath = path of signature file
InputStream inputStream = new FileInputStream(KeyFilePath);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate x509Certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
// input the signature bytes
String sigFile = signatureFilePath;
FileInputStream sigFileInputStream = new FileInputStream(sigFile);
byte[] sigToVerify = new byte[sigFileInputStream.available()];
sigFileInputStream.read(sigToVerify);
sigFileInputStream.close();
PublicKey pubKey = x509Certificate.getPublicKey();
Signature signature = Signature.getInstance(signAlgorithm);
signature.initVerify(pubKey);
// Update and verify the data
try {
FileInputStream dataFileInputStream = new FileInputStream(fileToVerify);
BufferedInputStream bufferedInputStream = new BufferedInputStream(dataFileInputStream);
byte[] buffer = new byte[IVerifyDigitalSignature.BYTE_SIZE];
int bufferedInputStreamLength;
while (bufferedInputStream.available() != IVerifyDigitalSignature.ZERO_LENGTH) {
bufferedInputStreamLength = bufferedInputStream.read(buffer);
signature.update(buffer, IVerifyDigitalSignature.ZERO_LENGTH, bufferedInputStreamLength);
}
bufferedInputStream.close();
// Verify the Signature
x509Certificate.verify(pubKey);
verifyDigitalSignature = signature.verify(sigToVerify);
请帮助我解决尚未关闭的问题。
【问题讨论】:
-
byte[] sigToVerify = new byte[sigFileInputStream.available()];被记录为InputStream.available()的错误使用,因此将其与零进行比较以作为流结束的测试。 -
自签名证书由其“自己的”密钥签名,或者更准确地说,由其公共部分在证书中的密钥对的私有部分签名。因此
x509certificate.verify(pubkey)成功了,但基本上没用,因为任何攻击者都可以自签名欺诈性证书。 CA 签名的证书由 CA(私有)密钥签名,因此子证书可以并且通常必须通过定位 parent (CA) 证书并使用 that i> pubkey,迭代直到你到达根 CA,它是自签名的,并且只能因为它是手动信任的(通常在信任库文件中)而被信任。 ... -
... 除了有效的签名之外,还需要检查证书链是否有效(不是伪造或泄露)的其他一些东西。这通常称为 PKI 验证,或更具体地称为 PKIX 验证,因为该格式(针对 Internet 配置的 X.509 证书等)是最常见的。对于 Java,docs.oracle.com/javase/7/docs/technotes/guides/security/… 是一个相当不错的起点。
-
感谢@dave_thompson_085 的回复。在我的情况下,我需要通过 Verisign 在 Java 问题中验证具有三个证书链的证书。那么这是否意味着我必须迭代三次才能到达根证书。根据您的评论,我了解到我们需要从 CA 证书中提取公钥。
-
能否请您告诉我,我需要哪些输入来验证签名,即证书类型、签名文件等。
标签: java security digital-signature