Certificate 证书密钥使用和密码加密模式
我正在尝试使用cxf和sprint加密传出的SOAP头。由于使用spring进行了配置,我最终使用OutiterCeptor作为客户端: " 方法,我逐步通过调试器找到其源:Certificate 证书密钥使用和密码加密模式,certificate,encryption,Certificate,Encryption,我正在尝试使用cxf和sprint加密传出的SOAP头。由于使用spring进行了配置,我最终使用OutiterCeptor作为客户端: " 方法,我逐步通过调试器找到其源: try { **cipher.init(Cipher.ENCRYPT_MODE, remoteCert);** } catch (InvalidKeyException e) { throw new WSSecurityException( WSSecurit
try {
**cipher.init(Cipher.ENCRYPT_MODE, remoteCert);**
} catch (InvalidKeyException e) {
throw new WSSecurityException(
WSSecurityException.FAILED_ENCRYPTION, null, null, e
);
}
此时它抛出:无效密钥使用“异常
最后我编写了一个测试java类,在该类中我手动读取证书,然后尝试使用Cipher.ENCRYPT\u MODE参数初始化密码,
我最终得到了相同的异常。以下是具体的代码片段:
InputStream inStream = new FileInputStream("our_cert.cer");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert =(X509Certificate)cf.generateCertificate(inStream);
inStream.close();
// Read the public key from certificate file
RSAPublicKey pubkey = (RSAPublicKey) cert.getPublicKey();
cipher.init(Cipher. ENCRYPT_MODE, certif); // it breaks at this point
我将最后一行替换为
cipher.init(Cipher. PRIVATE_KEY, certif);
而且一切顺利
我认为这不是正确的密钥用法,我认为加密模式也应该有效
通过查看证书密钥使用部分,我注意到它的密钥使用定义如下:
ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
它没有其他的关键部分
从其作用方式来看,Cipher.init(..)似乎只适用于数字签名(即密码.私钥),而不适用于密钥加密(即密码.加密模式)
因此,我的问题是,KeyUsage是否可能没有为该证书正确定义。
我不是密码专家,但我读过的一些留言板建议,如果密钥使用是关键的,可能需要使用
数据加密以及
谢谢你的帮助 在中,有两种情况会引发该异常,一种是“永不发生”错误,另一种是检查相关证书是否支持相关操作
if (critSet != null && !critSet.isEmpty()
&& critSet.contains(KEY_USAGE_EXTENSION_OID)) {
boolean[] keyUsageInfo = cert.getKeyUsage();
// keyUsageInfo[2] is for keyEncipherment;
// keyUsageInfo[3] is for dataEncipherment.
if ((keyUsageInfo != null) &&
(((opmode == Cipher.ENCRYPT_MODE) &&
(keyUsageInfo.length > 3) &&
(keyUsageInfo[3] == false)) ||
((opmode == Cipher.WRAP_MODE) &&
(keyUsageInfo.length > 2) &&
(keyUsageInfo[2] == false)))) {
throw new InvalidKeyException("Wrong key usage");
}
}
这表明您使用的证书对加密无效。也许您试图使用公钥证书进行加密
代码似乎没有检查像私钥一样总是无效的opmode,而只是检查像加密模式一样有时无效的opmode,这可能就是为什么您的测试代码没有问题。最近遇到了这个问题。如果公钥证书创建正确,则可以使用公钥证书进行加密。证书应具有密钥使用对象ID(ObjectId:2.5.29.15 Criticality=true),设置为“b0”(10110000),基本上启用了数据加密位。否则,您将遇到错误的密钥使用错误。任何CA颁发的证书都将使密钥使用关键性变为true。自签名证书(如在dev/sandbox环境中)不会将临界值设置为true,因此这些证书可以工作,当然前提是您已设置为信任它们。 我尝试使用服务器上的公钥证书,但遇到了这个错误。然后我们的IT部门拿着用于数据加密的正确公钥证书回来了,它开始为我工作。是的,通过调试Cipher.init(),我确实看到第一个条件得到了满足,即:
(keyUsageInfo!=null)&((opmode==Cipher.ENCRYPT_MODE)&&(keyUsageInfo.length>3)&(keyUsageInfo[3]==false)
证书中的密钥使用应该支持加密,因为它有以下部分:ObjectId:2.5.29.15 Criticality=true-Keyusage[DigitalSignature Key\u encryption]
还是我误读了它?非常感谢!我相信你在寻找“数据加密”而不是“密钥加密”我想那应该是Cipher.WRAP_模式。
ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
if (critSet != null && !critSet.isEmpty()
&& critSet.contains(KEY_USAGE_EXTENSION_OID)) {
boolean[] keyUsageInfo = cert.getKeyUsage();
// keyUsageInfo[2] is for keyEncipherment;
// keyUsageInfo[3] is for dataEncipherment.
if ((keyUsageInfo != null) &&
(((opmode == Cipher.ENCRYPT_MODE) &&
(keyUsageInfo.length > 3) &&
(keyUsageInfo[3] == false)) ||
((opmode == Cipher.WRAP_MODE) &&
(keyUsageInfo.length > 2) &&
(keyUsageInfo[2] == false)))) {
throw new InvalidKeyException("Wrong key usage");
}
}