cxf と sprint を使用して、発信 SOAP ヘッダーを暗号化しようとしています。春の構成の結果として、クライアントに outInterceptor を使用することになります。
'
<bean id="encryptOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken Timestamp Encrypt" />
<entry key="passwordCallbackRef" value-ref="passwordCallback" />
<entry key="user" value="mykey" />
<entry key="encryptionPropFile" value="keystore.properties" />
</map>
</constructor-arg>
</bean>
`
そして、この結果として、それは呼び出すことになります
`org.apache.ws.security.message.WSSecEncryptedKey.prepareInternal()`
メソッド、私はデバッガーをそのソースにステップスルーしました:
try {
**cipher.init(Cipher.ENCRYPT_MODE, remoteCert);**
} catch (InvalidKeyException e) {
throw new WSSecurityException(
WSSecurityException.FAILED_ENCRYPTION, null, null, e
);
}
その時点で、「無効なキーの使用法」例外がスローされます。
私は手動で証明書を読んでいるテストJavaクラスを書いてしまい、Cipher.ENCRYPT_MODEパラメータでCipherを初期化しようとしましたが、結局同じ例外が発生しました.hereは特定のスニペットです:
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);
そして無事通過。
ただし、それは正しいキーの使用法ではないと思います。また、ENCRYPT_MODEも機能するはずだと思います。
証明書のキー使用法セクションを見ると、キー使用法が次のように定義されていることに気付きました。
ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
他のクリティカル セクションはありません。
それが動作する方法から、Cipher.init(..)はDigitalSignature (つまりCipher. PRIVATE_KEY ) に対してのみ機能し、 Key_Encipherment (つまりCipher. ENCRYPT_MODE ) に対しては機能しないようです。
私の質問は、その証明書に対してKeyUsageが正しく定義されていない可能性があるということです。私は暗号化の専門家ではありませんが、私が読んでいた掲示板では、keyUsage が重要な場合は DATA_ENCIPHERMENT も使用する必要があるかもしれないと示唆されて いました…</p>
ご協力ありがとうございました!