RSA加密解密和数字签名

来源:互联网 发布:windows update不见了 编辑:程序博客网 时间:2024/05/01 04:16

上网研究了一下RSA加密解密和作为数字签名的用法,整理了一下,写了一个类,总结了用法。

用到了commons-codec-1.6.jar的Base64类

package tj.rsa_pkcs;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;import org.apache.commons.codec.CharEncoding;import org.apache.commons.codec.binary.Base64;public class T1 {static final String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANQCoC6334MPhQWnfTDUZ7N1P2clRTfoDp/uMCClSMY1Ptf57nMYa87QbzSui61/9xtNKr1MJ2vCff2La5Dp0vGcWyTOKebva1QgPs/G8Vm7wG2QtB4vlkEj0Mfga2IEbTrz8Drk4wSO8gKNjI9E8EnoBKKcUTAjJsgDiPoUP6YRAgMBAAECgYEAlI2WccXTLoFUYwbd+LYMR7mzCHIcEzVd8gAy5t0JpiCu/SSaSTlmaQ6xrUdUheixXAbxGJzgzmgEYgEsCOleLTkg5+cUp0MJ7SfoEdrz/dtjp9+M2CQMpCUVRVoHlJLbRB3AEwo+PEnefu/gkx6k2E/sEuzDbiopQpO1ZcWsnvECQQDuax56efeAiijve2cmtDbkICuEX6db1we/+cwUawp0E5grADI7VGA//z2RUl/wBn+okeVZdNrx2ls5WvXhS7UNAkEA46T4m3+lAA6nAIBHRCksgFPWWP2Per22WyblUr6Sp3sYjtBUx10znQexV9t2sBP4Gg++NbUv3yKIKBZWa9X8FQJBAKZ8Xrgf21kDITq57Xn1di8u17SEJxXWvi6sfHn1lUMhO60rYehULzIBRjjoUN4Ha7WGy6UAGLOySuluPyyn9TECQGzW5V5DazpZxxMAQhKetP4uF1+46669ocB3GlGzeB7HRfiSNtaTAyhjEzF0ZozNH2QmfsTi+h5vPjYcZ/lq9/kCQQCwDYpT2Pz2bmmESyJIjjgLLvyoa1irG0sNvFtNczayj25IzTSTQttBdByi5zteoO2sDvHOAxaE/pdL9HM64bNE";static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUAqAut9+DD4UFp30w1GezdT9nJUU36A6f7jAgpUjGNT7X+e5zGGvO0G80routf/cbTSq9TCdrwn39i2uQ6dLxnFskzinm72tUID7PxvFZu8BtkLQeL5ZBI9DH4GtiBG068/A65OMEjvICjYyPRPBJ6ASinFEwIybIA4j6FD+mEQIDAQAB";/** * 加密算法RSA */static final String algorithm = "RSA";/** * 初始化,生成私钥和公钥 *  * @param  * @return void * @author Administrator  * @throws NoSuchAlgorithmException  * @Create 2015年4月16日 下午3:45:07 * @Modify {修改人1} {修改时间1} {修改目的1} */public static void initKey() throws NoSuchAlgorithmException{KeyPairGenerator kpg = KeyPairGenerator.getInstance(algorithm);kpg.initialize(1024);kpg.genKeyPair().getPrivate(); KeyPair keyPair = kpg.generateKeyPair();        //公钥        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();        System.out.println("--------------------------------public key --------------------------------");        System.out.println(Base64.encodeBase64String(publicKey.getEncoded()));        //私钥        System.out.println("--------------------------------private key --------------------------------");        RSAPrivateKey privateKey =  (RSAPrivateKey) keyPair.getPrivate();        System.out.println(Base64.encodeBase64String(privateKey.getEncoded()));}/** * 用私钥加密 *  * @param @param input * @param @param privateKey * @param @return * @param @throws NoSuchAlgorithmException * @param @throws Exception * @return String * @author Administrator  * @Create 2015年4月16日 下午4:26:04 * @Modify {修改人1} {修改时间1} {修改目的1} */public static byte[] encryptByPrivateKey(byte[] input,String privateKey) throws NoSuchAlgorithmException, Exception{//解密私钥,生成PKCS8EncodedKeySpec对象//PKCS8EncodedKeySpec的JDK描述:此类表示按照 ASN.1 类型 PrivateKeyInfo 进行编码的专用密钥的 ASN.1 编码//PKCS8EncodedKeySpec用于私钥PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));//生成RSA 加密工厂类KeyFactory keyFactory = KeyFactory.getInstance(algorithm);//生成加密的KeyKey key = keyFactory.generatePrivate(keySpec);//创建Cipher对象(此类为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心。)Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//初始化Cipher,设置模式为加密模式cipher.init(Cipher.ENCRYPT_MODE, key);//对数据进行加密byte[] resultBytes = cipher.doFinal(input);return resultBytes;}/** * 用公钥解密 *  * @param @param fromContent * @param @param publicKey * @param @param charset * @param @return * @param @throws Exception * @return String * @author Administrator  * @Create 2015年4月16日 下午3:44:02 * @Modify {修改人1} {修改时间1} {修改目的1} */public static byte[] decryptByPublicKey(byte[] data,String publicKey) throws Exception{//解密公钥,生成X509EncodedKeySpec对象//X509EncodedKeySpec的JDK描述:此类表示根据 ASN.1 类型 SubjectPublicKeyInfo 进行编码的公用密钥的 ASN.1 编码//X509EncodedKeySpec用于公钥X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));//生成RSA 加密工厂类KeyFactory keyFactory = KeyFactory.getInstance(algorithm);//生成加密的KeyKey key = keyFactory.generatePublic(keySpec);//创建Cipher对象(此类为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心。)Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//初始化Cipher,设置模式为解密模式cipher.init(Cipher.DECRYPT_MODE, key);//rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密InputStream is = new ByteArrayInputStream(data);ByteArrayOutputStream write = new ByteArrayOutputStream();byte[] buff = new byte[128];int buffl ;while((buffl=is.read(buff))!=-1){byte[] block = null;if(buffl==buff.length){block = buff;}else {block = new byte[buffl];                for (int i = 0; i < buffl; i++) {                    block[i] = buff[i];                }}write.write(cipher.doFinal(block));}return write.toByteArray();}/** * 用公钥加密 *  * @param @param input * @param @param publicKey * @param @return * @param @throws Exception * @return byte[] * @author Administrator  * @Create 2015年4月16日 下午4:44:12 * @Modify {修改人1} {修改时间1} {修改目的1} */public static byte[] encryptByPublicKey(byte[] input,String publicKey) throws Exception{//解密公钥,生成KeySpec对象X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));//生成RSA 加密工厂类KeyFactory keyFactory = KeyFactory.getInstance(algorithm);//生成加密的KeyKey key = keyFactory.generatePublic(keySpec);//创建Cipher对象(此类为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心。)Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//初始化Cipher,设置模式为加密模式cipher.init(Cipher.ENCRYPT_MODE, key);//对数据进行加密byte[] resultBytes = cipher.doFinal(input);return resultBytes;}/** * 用私钥解密 *  * @param @param data * @param @param privateKey * @param @return * @param @throws Exception * @return byte[] * @author Administrator  * @Create 2015年4月16日 下午4:44:58 * @Modify {修改人1} {修改时间1} {修改目的1} */public static byte[] decryptByPrivateKey(byte[] data,String privateKey) throws Exception{//解密公钥,生成KeySpec对象PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));//生成RSA 加密工厂类KeyFactory keyFactory = KeyFactory.getInstance(algorithm);//生成加密的KeyKey key = keyFactory.generatePrivate(keySpec);//创建Cipher对象(此类为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心。)Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//初始化Cipher,设置模式为解密模式cipher.init(Cipher.DECRYPT_MODE, key);//rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密InputStream is = new ByteArrayInputStream(data);ByteArrayOutputStream write = new ByteArrayOutputStream();byte[] buff = new byte[128];int buffl ;while((buffl=is.read(buff))!=-1){byte[] block = null;if(buffl==buff.length){block = buff;}else {block = new byte[buffl];                for (int i = 0; i < buffl; i++) {                    block[i] = buff[i];                }}write.write(cipher.doFinal(block));}return write.toByteArray();}/** * 签名算法 也可以是MD5withRSA或者其他 */static final String  SIGN_ALGORITHMS = "SHA1WithRSA";/** * 对数据进行签名 *  * @param @param content * @param @param privateKey * @param @param charset * @param @return * @return String * @author Administrator  * @throws Exception  * @Create 2015年4月16日 下午4:49:24 * @Modify {修改人1} {修改时间1} {修改目的1} */public static String sign(String content,String privateKey,String charset) throws Exception{PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));KeyFactory keyFactory = KeyFactory.getInstance(algorithm);PrivateKey key = keyFactory.generatePrivate(keySpec);//生成签名对象Signature signature = Signature.getInstance(SIGN_ALGORITHMS);//通过私钥初始化signature.initSign(key);//写入要签名的数据signature.update(content.getBytes(charset));//获得签名后的数据byte[] signData = signature.sign();//进行base64编码后返回return Base64.encodeBase64String(signData);}/** * 校验签名数据是否正确 *  * @param @param content * @param @param signStr * @param @param publicKey * @param @param charset * @param @return * @param @throws Exception * @return boolean * @author Administrator  * @Create 2015年4月16日 下午5:06:42 * @Modify {修改人1} {修改时间1} {修改目的1} */public static boolean verify(String content,String signStr,String publicKey,String charset) throws Exception{X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));KeyFactory keyFactory = KeyFactory.getInstance(algorithm);PublicKey key = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGN_ALGORITHMS);//初始化校验signature.initVerify(key);//更新数据到签名对象signature.update(content.getBytes(charset));//校验 因为这里的signStr之前签名后是base加密的,所以这里要先base64解密boolean isVerify = signature.verify(Base64.decodeBase64(signStr));return isVerify;}public static void main(String[] args) throws Exception {//初始化key//initKey();String content = "123";System.out.println("------------------下面是公钥加密和私钥解密------------------");//对数据进行加密byte[] encryptedData = encryptByPublicKey(content.getBytes(), publicKey);String encryptedStr = Base64.encodeBase64String(encryptedData);System.out.println("加密后的字符串:"+encryptedStr);//解密byte[] s = decryptByPrivateKey(Base64.decodeBase64(encryptedStr), privateKey);//byte[] s = decryptByPrivateKey(encryptedData, privateKey);//直接使用加密后的byte数组就行System.out.println("解密后:"+new String(s));System.out.println("------------------下面是私钥加密和公钥解密------------------");//对数据进行加密byte[] encryptedData2 = encryptByPrivateKey(content.getBytes(), privateKey);//解密byte[] s2 = decryptByPublicKey(encryptedData2, publicKey);//直接使用加密后的byte数组就行System.out.println("解密后:"+new String(s2));System.out.println("------------------下面是签名和签名验证------------------");String signStr = sign(content, privateKey, CharEncoding.UTF_8);System.out.println("签名数据:"+signStr);System.out.println("签名验证结果:"+verify("223", signStr, publicKey, CharEncoding.UTF_8));System.out.println("签名验证结果:"+verify("123", signStr, publicKey, CharEncoding.UTF_8));}}


0 0
原创粉丝点击