Java的安全学习(包括加密,数字签名,证书和认证) JCA JCE

ChinaWin 2014-08-21

packagedemo.jca.rsa;

importstaticorg.junit.Assert.*;

importorg.junit.Before;

importorg.junit.Test;

importdemo.jca.keystore.Coder;

importjava.security.Key;

importjava.security.KeyFactory;

importjava.security.KeyPair;

importjava.security.KeyPairGenerator;

importjava.security.PrivateKey;

importjava.security.PublicKey;

importjava.security.Signature;

importjava.security.interfaces.RSAPrivateKey;

importjava.security.interfaces.RSAPublicKey;

importjava.security.spec.PKCS8EncodedKeySpec;

importjava.security.spec.X509EncodedKeySpec;

importjava.util.HashMap;

importjava.util.Map;

importjavax.crypto.Cipher;

/**

*

*RSA这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。<br>

*RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。<br>

*数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输过程中不被修改。

*<ul>

*流程分析:

*<li>甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。</li>

*<li>甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。</li>

*<li>乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。</li>

*<ul>

*

*@authorXinZhang

*@version1.0

*@since1.0

*/

publicclassRSACoderTest{

privateStringpublicKey;

privateStringprivateKey;

@Before

publicvoidsetUp()throwsException{

Map<String,Object>keyMap=RSACoder.initKey();

publicKey=RSACoder.getPublicKey(keyMap);

privateKey=RSACoder.getPrivateKey(keyMap);

System.err.println("公钥:\n\r"+publicKey);

System.err.println("私钥:\n\r"+privateKey);

}

@Test

publicvoidtest()throwsException{

System.err.println("公钥加密——私钥解密");

StringinputStr="abc";

byte[]data=inputStr.getBytes();

byte[]encodedData=RSACoder.encryptByPublicKey(data,publicKey);

byte[]decodedData=RSACoder.decryptByPrivateKey(encodedData,privateKey);

StringoutputStr=newString(decodedData);

System.err.println("加密前:"+inputStr+"\n\r"+"解密后:"+outputStr);

assertEquals(inputStr,outputStr);

}

@Test

publicvoidtestSign()throwsException{

System.err.println("私钥加密——公钥解密");

StringinputStr="sign";

byte[]data=inputStr.getBytes();

byte[]encodedData=RSACoder.encryptByPrivateKey(data,privateKey);

byte[]decodedData=RSACoder.decryptByPublicKey(encodedData,publicKey);

StringoutputStr=newString(decodedData);

System.err.println("加密前:"+inputStr+"\n\r"+"解密后:"+outputStr);

assertEquals(inputStr,outputStr);

System.err.println("私钥签名——公钥验证签名");

//产生签名

Stringsign=RSACoder.sign(encodedData,privateKey);

System.err.println("签名:\r"+sign);

//验证签名

booleanstatus=RSACoder.verify(encodedData,publicKey,sign);

System.err.println("状态:\r"+status);

assertTrue(status);

}

}

abstractclassRSACoderextendsCoder{

publicstaticfinalStringKEY_ALGORITHM="RSA";

publicstaticfinalStringSIGNATURE_ALGORITHM="MD5withRSA";

privatestaticfinalStringPUBLIC_KEY="RSAPublicKey";

privatestaticfinalStringPRIVATE_KEY="RSAPrivateKey";

/**

*用私钥对信息生成数字签名

*

*@paramdata

*加密数据

*@paramprivateKey

*私钥

*

*@return

*@throwsException

*/

publicstaticStringsign(byte[]data,StringprivateKey)throwsException{

//解密由base64编码的私钥

byte[]keyBytes=decryptBASE64(privateKey);

//构造PKCS8EncodedKeySpec对象

PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);

//KEY_ALGORITHM指定的加密算法

KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM);

//取私钥匙对象

PrivateKeypriKey=keyFactory.generatePrivate(pkcs8KeySpec);

//用私钥对信息生成数字签名

Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initSign(priKey);

signature.update(data);

returnencryptBASE64(signature.sign());

}

/**

*校验数字签名

*

*@paramdata

*加密数据

*@parampublicKey

*公钥

*@paramsign

*数字签名

*

*@return校验成功返回true失败返回false

*@throwsException

*

*/

publicstaticbooleanverify(byte[]data,StringpublicKey,Stringsign)

throwsException{

//解密由base64编码的公钥

byte[]keyBytes=decryptBASE64(publicKey);

//构造X509EncodedKeySpec对象

X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes);

//KEY_ALGORITHM指定的加密算法

KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM);

//取公钥匙对象

PublicKeypubKey=keyFactory.generatePublic(keySpec);

Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initVerify(pubKey);

signature.update(data);

//验证签名是否正常

returnsignature.verify(decryptBASE64(sign));

}

/**

*解密<br>

*用私钥解密http://www.5a520.cnhttp://www.feng123.com

*

*@paramdata

*@paramkey

*@return

*@throwsException

*/

publicstaticbyte[]decryptByPrivateKey(byte[]data,Stringkey)

throwsException{

//对密钥解密

byte[]keyBytes=decryptBASE64(key);

//取得私钥

PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);

KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM);

KeyprivateKey=keyFactory.generatePrivate(pkcs8KeySpec);

//对数据解密

Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE,privateKey);

returncipher.doFinal(data);

}

/**

*解密<br>

*用私钥解密

*

*@paramdata

*@paramkey

*@return

*@throwsException

*/

publicstaticbyte[]decryptByPublicKey(byte[]data,Stringkey)

throwsException{

//对密钥解密

byte[]keyBytes=decryptBASE64(key);

//取得公钥

X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);

KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM);

KeypublicKey=keyFactory.generatePublic(x509KeySpec);

//对数据解密

Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE,publicKey);

returncipher.doFinal(data);

}

/**

*加密<br>

*用公钥加密

*

*@paramdata

*@paramkey

*@return

*@throwsException

*/

publicstaticbyte[]encryptByPublicKey(byte[]data,Stringkey)

throwsException{

//对公钥解密

byte[]keyBytes=decryptBASE64(key);

//取得公钥

X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);

KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM);

KeypublicKey=keyFactory.generatePublic(x509KeySpec);

//对数据加密

Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE,publicKey);

returncipher.doFinal(data);

}

/**

*加密<br>

*用私钥加密

*

*@paramdata

*@paramkey

*@return

*@throwsException

*/

publicstaticbyte[]encryptByPrivateKey(byte[]data,Stringkey)

throwsException{

//对密钥解密

byte[]keyBytes=decryptBASE64(key);

//取得私钥

PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);

KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM);

KeyprivateKey=keyFactory.generatePrivate(pkcs8KeySpec);

//对数据加密

Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE,privateKey);

returncipher.doFinal(data);

}

/**

*取得私钥

*

*@paramkeyMap

*@return

*@throwsException

*/

publicstaticStringgetPrivateKey(Map<String,Object>keyMap)

throwsException{

Keykey=(Key)keyMap.get(PRIVATE_KEY);

returnencryptBASE64(key.getEncoded());

}

/**

*取得公钥

*

*@paramkeyMap

*@return

*@throwsException

*/

publicstaticStringgetPublicKey(Map<String,Object>keyMap)

throwsException{

Keykey=(Key)keyMap.get(PUBLIC_KEY);

returnencryptBASE64(key.getEncoded());

}

/**

*初始化密钥

*

*@return

*@throwsException

*/

publicstaticMap<String,Object>initKey()throwsException{

KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance(KEY_ALGORITHM);

keyPairGen.initialize(1024);

KeyPairkeyPair=keyPairGen.generateKeyPair();

//公钥

RSAPublicKeypublicKey=(RSAPublicKey)keyPair.getPublic();

//私钥

RSAPrivateKeyprivateKey=(RSAPrivateKey)keyPair.getPrivate();

Map<String,Object>keyMap=newHashMap<String,Object>(2);

keyMap.put(PUBLIC_KEY,publicKey);

keyMap.put(PRIVATE_KEY,privateKey);

returnkeyMap;

}

}

相关推荐