论Java加密技术与Windows的结合 (9)
new RSAPrivateKeySpec(mod, exp);
KeyFactory kf = KeyFactory.getInstance("RSA");
privkey = kf.generatePrivate(privKeySpec);
return privkey;
}
RSA Signature Provider
java.security.SignatureSpi类有五个方法:
· engineInitSign()为签名初试化RSA签名引擎。
· engineInitVerify()为确认一个签名初试化RSA签名引擎。
· engineUpdate()增加数据到签名或确认操作。
· engineSign()完成签名操作并返回数字签名。
· engineVerify()完成签名-确认过程,如果签名是正确的,返回true。
记住,数字签名需要私钥,确认一个数字签名需要公钥。如果我们有权使用Microsoft的私钥——即,私钥是可输出的——就没必要在Microsoft本地代码中执行RSA签名操作了。但是在有些情况下(例如,如果我们运用一个加密了的智能卡),我们无权使用私钥。如果私钥是不能输出的,我们必须用Microsoft本地代码进行数字签名。
如果Java程序运用KeyManager的方法getPrivateKey()来获取私钥,私钥的别名就被缓存起来。当RSA Signature Provider进行签名时,我们就重用缓存的别名,并调用Microsoft本地函数来执行签名操作而不用暴露私钥。(这听起来有些虚假,但确实可行。)注意,在engineInitSign()中没有用私钥。我用Java JCE哈希函数来进行运算,然后用Microsoft Cryptographic Provider从哈希文件中生成RSA签名。
通过添加一个engineInitSign(字符串别名)方法,可以改进Java Signature类:
MSCryptoFunctions MSF =
new MSCryptoFunctions();
protected void engineInitSign(
PrivateKey privateKey) {
MSF.MSrsaSignInit((byte[])null,
"MD5");
}
protected byte[] engineSign() {
byte[] hash = MD5.digest();
byte[] mssig =
MSF.MSrsaSignHash(hash,
(byte[])null, "MD5");
return mssig;
}
我们可以在Microsoft本地代码中实现签名-确认,但这么做没有优势。在实现过程中,我们运用了JSSE提供者在Java中执行确认:
protected void engineInitVerify(
PublicKey publicKey) {
jsse = Signature.getInstance(
"MD5withRSA", "SunJSSE");
jsse.initVerify(publicKey);
}
protected boolean engineVerify(
byte[] sigBytes) {
boolean verifyresult=false;
verifyresult =
jsse.verify(sigBytes);
return verifyresult;
}
RSA Cipher Provider
javax.Crypto.CipherSpi类有12个方法:
· engineInit()初试化密码提供者(cipher provider)。
· engineUpdate()继续一个由多个部分组成的加密或解密操作。
· engineDoFinal()加密或解密一个单一操作中的数据,或完成一个由多个部分组成的操作。
· engineGetBlockSize()返回字区大小(以字节形式)。
· engineGetIV()返回初试化向量。它不用于RSA密码。
· engineGetKeySize()返回一个特定的钥匙对象的钥匙大小。
· engineGetOutputSize()以字节形式返回输出长度,输出缓冲器需要这个长度来保存下一个update或doFinal操作的结果,输入长度已假定。
· engineGetParameters()返回这个密码运用的参数。
· engineSetMode()设置密码的模式(加密或解密)。
· engineSetPaddi


您的位置:
