⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 论java加密技术与windows的结合.txt

📁 论Java加密技术与Windows的结合
💻 TXT
📖 第 1 页 / 共 3 页
字号:
match = true;
cert = issuerArray[i];
subject = cert.getSubjectDN();
issuer = cert.getIssuerDN();
CertChainList.add(cert);
break;
}
if (!match) {
return null; // cert chain broken
}
}
} catch (Exception e) {
e.printStackTrace(); 
}

X509Certificate[] CertChain =
new X509Certificate[CertChainList.size()];
CertChainList.toArray(CertChain);

return CertChain; 
}
 

  getPrivateKey()方法为一个别名返回私钥,假设私钥可以从Microsoft钥匙库中输出。记住,有时私钥是不能输出的。(例如,如果你用了一个加密了的智能卡,那么就没人可以从智能卡上读取私钥了。)如果不能输出私钥,getPrivateKey()就返回一个虚拟的私钥。所以,如果getPrivateKey()不能得到私钥,我们就骗Java,让它认为得到了私钥。getPrivateKey()也缓存别名,所以,当一个Java程序试图执行一个RSA数字签名函数时,我们就会知道运用哪个私钥了(缓存的别名),而且Microsoft加密提供者就可以执行我们想要的RSA签名或解密函数了(见列表7)。


方法getPrivateKey()为一个别名返回私钥,假设私钥可以从Windows钥匙库中输出。 
MSCryptoFunctions MSF = new MSCryptoFunctions();
public PrivateKey getPrivateKey(String alias) { 
// get the private key from MS Windows for 
// this alias
byte[] keyblob = MSF.MSgetPrivateKey(alias);

if (keyblob == null) { // generate a dummy key
byte[] modblob = new byte[128];
for(i=0; i<128; i++) 
modblob[i] = 127;
mod = new BigInteger(modblob);
exp = mod;

} else { // use the key that got exported
for(i=0; i
modblob[i] = keyblob[19-i+(keysize/16)*2];
expblob[i] = keyblob[19-i+(keysize/16)*9];
}
mod = new BigInteger(1, modblob);
exp = new BigInteger(1, expblob);
}
RSAPrivateKeySpec privKeySpec = 
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()设置密码的模式(加密或解密)。 
  · engineSetPadding()设置这个密码的填充机制(当前只支持PKCS1填充)。 
  · engineWrap()封装一个钥匙(未实现)。 
  · engineUnwrap()解开一个钥匙(未实现)。

  RSA加密过程需要公钥;RSA解密需要私钥。如果我们有权使用Microsoft钥匙库中的RSA私钥——即,私钥是可以输出的——那么就没必要在Microsoft本地代码中执行RSA密码操作。但在有些情况下(例如,如果我们运用一个加密了的智能卡),我们就无权使用私钥。如果私钥是不能输出的,我们必须用Microsoft本地代码进行RSA解密。

  RSA密码在Windows本地代码中的实现很简单。本质的解密过程如下:

MSrsaDecrypt (jstring jpadalg, 
jbyteArray jdata) {
CryptAcquireContext(
&hDecryptProv, alias, NULL, 
PROV_RSA_FULL,0);
CryptGetUserKey(hDecryptProv, 
AT_KEYEXCHANGE, &hDecryptKey);
CryptDecrypt(hDecryptKey, 0, 
TRUE, 0, encryptblob, &ndata);
return decryptblob;
} 

  加密几乎是一样的。因为RSA加密只需要公钥,加密模式可以在Java中执行。我选择在Windows本地代码中实现RSA加密和解密,因为这很容易。 

  RSA密码是一个美国政府控制的加密算法。如果你想将RSA cipher provider同Sun JCE结合起来运用,你必须创建一个JAR文件,用一个DSA钥匙签署它,然后添加一个由Sun Microsystems签发的证书。为了方便,我已经把所有的mscrypto-class文件放在了一个单一的包中(com.boyter.mscrypto)。在签署的JAR文件中,只需要有MSRSACipherProvider.class和MSRSACipherFactoryImpl.class。用来创建和签名JAR文件的Windows命令是:

jar cvf mscrypto.jar com
jarsigner -keystore keystore 
-storepass foobar mscrypto.jar 
jcesigner 

  你可以从“How to Implement a Provider for the Java Cryptography Extension 1.2.1.”(见资源)的第五步找到关于从Sun获取一个JCE代码签署的证书的说明。如果你想避免JCE的局限性(如美国政府的输出控制),你可以用一个clean-room式的实现环境(如BeeJCE)来代替JCE。我提供了一个称为msrsatest.java的程序,可以用来测试Microsoft 加密的RSA签名和RSA密码提供者。为此,你必须在Microsoft Windows中安装一个RSA私钥和证书。

  有根据的运用理由

  将Java安全特征同本地Microsoft Windows安全平台结合起来有许多好的理由,包括减少了的管理费用、CRL确认和与智能卡的兼容。将Java JCE同Windows证书和钥匙库结合起来的另一个理由是用来管理Java证书和钥匙库的Java工具很麻烦。Microsoft平台有一个更好的图形用户界面(GUI)用来管理Windows钥匙和证书库。你可以通过运行CERTMGR.EXT程序(与Windows平台SDK在一起)来启动GUI,或者你可以从IE窗口来启动:运用下拉菜单Tools | Internet Option,选择Content键,然后选择Certificates。

  在将Microsoft 加密支持的KeyManager和TrustManager用于JSSE时,你不会有什么问题。Microsoft 加密支持的RSA Signature Provider和RSA Cipher Provider也可以运行,但不能用于JSSE。



上一页  1 2 3 4 5  




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -