RSA加密解密和数字签名

上网研究了一下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);
		//生成加密的Key
		Key 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);
		//生成加密的Key
		Key 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);
		//生成加密的Key
		Key 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);
		//生成加密的Key
		Key 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));
		}

}


转载于:https://my.oschina.net/forai/blog/777127

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值