欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RSA加解密

程序员文章站 2022-03-04 15:38:09
...
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * 产生公钥和私钥对,并且保存在文件中,公钥 pk.dat,私钥 sk.dat
 *  
 */
public class RSAKeyPairGenerator {
	public static void main(String[] args) throws Exception {
		// 加密的种子信息
		byte []seed = "zhangxy@lexiang100".getBytes();
		RSAKeyPairGenerator kg = new RSAKeyPairGenerator();
		kg.genKeys(seed);
	}

	/**
	 * 生成密钥
	 * 
	 * @param keyInfo
	 * @throws Exception
	 */
	public void genKeys(byte []seed) throws Exception {
		// 密钥对生成器
		KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
		SecureRandom random = new SecureRandom();
		random.setSeed(seed);
		keygen.initialize(1024, random);
		KeyPair keyPair = keygen.generateKeyPair();

		// 生成公钥
		RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
		saveFile(publicKey, "pk.dat");

		// 生成私钥
		RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
		saveFile(privateKey, "sk.dat");
		System.out.println(publicKey.toString());
		System.out.println(publicKey.toString());

		System.out.println("公钥 modulus        >>> " + publicKey.getModulus());
		System.out.println("公钥 publicExponent >>> " + publicKey.getPublicExponent());
		
		System.out.println("私钥 modulus        >>> " + privateKey.getModulus());
		System.out.println("私钥 publicExponent >>> " + privateKey.getPrivateExponent());
	}

	private void saveFile(Object obj, String fileName) throws Exception {
		ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(fileName));
		output.writeObject(obj);
		output.close();
	}
}

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
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.RSAPublicKeySpec;

import javax.crypto.Cipher;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class RSAUtil {
	public static void main(String[] args) throws Exception {
		String str = "My chinese name is Mr.Z!";
		System.out.println("原始文本:" + str);
		RSAUtil rsa = new RSAUtil();
		// 私钥
		RSAPrivateKey privateKey = (RSAPrivateKey) rsa.readFromFile("sk.dat");
		// 公钥
		RSAPublicKey publickKey = (RSAPublicKey) rsa.readFromFile("pk.dat");
		byte[] encbyte = rsa.encrypt(str, privateKey);
		System.out.println("私钥加密:");
		String encStr = toHexString(encbyte);
		System.out.println(encStr);
		
		byte[] signBytes = rsa.sign(str, privateKey);
		System.out.println("私钥签名:");
		String signStr = toHexString(signBytes);
		System.out.println(signStr);
		
		System.out.println("公钥验证签名:");
		if (rsa.verifySign(str, signStr, publickKey)) {
			System.out.println("RSA sign check success");
		} else {
			System.out.println("RSA sign check failure");
		}
		
		byte[] decByte = rsa.decrypt(encStr, publickKey);
		System.out.println("公钥解密:");
		String decStr = new String(decByte);
		System.out.println(decStr);
	}
	
	/**
	 * 获取公钥
	 * 
	 * @param modulus
	 * @param publicExponent
	 * @return
	 * @throws Exception
	 */
	public static PublicKey getPublicKey() {
		PublicKey publicKey = null;
		String modulus = 

"14086566523754439857763879199332120114399179109937025293469996396388705802697953127591764545189368534601365

433393175760359319373977698652594369746999669370499575326633159323339503808869829930818061221571354457746261

3426793519824197226393059683065343801412208205295045502348474411031999124137863144916358656019";
		String publicExponent = "65537";
		BigInteger m = new BigInteger(modulus);
		BigInteger e = new BigInteger(publicExponent);
		RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);

		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
			publicKey = keyFactory.generatePublic(keySpec);
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		return publicKey;
	}

	/**
	 * 加密,key可以是公钥,也可以是私钥
	 * 
	 * @param message
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public byte[] encrypt(String message, Key key) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(message.getBytes("gb2312"));
	}

	/**
	 * 解密,key可以是公钥,也可以是私钥,如果是公钥加密就用私钥解密,反之亦然
	 * 
	 * @param message
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public byte[] decrypt(String message, Key key) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
		cipher.init(Cipher.DECRYPT_MODE, key);
		return cipher.doFinal(toBytes(message));
	}

	/**
	 * 用私钥签名
	 * 
	 * @param message
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public byte[] sign(String message, PrivateKey key) throws Exception {
		Signature signetcheck = Signature.getInstance("MD5withRSA");
		signetcheck.initSign(key);
		signetcheck.update(message.getBytes("ISO-8859-1"));
		return signetcheck.sign();
	}

	/**
	 * 用公钥验证签名的正确性
	 * 
	 * @param message
	 * @param signStr
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public boolean verifySign(String message, String signStr, PublicKey key) throws Exception {
		if (message == null || signStr == null || key == null) {
			return false;
		}
		Signature signetcheck = Signature.getInstance("MD5withRSA");
		signetcheck.initVerify(key);
		signetcheck.update(message.getBytes("ISO-8859-1"));
		return signetcheck.verify(toBytes(signStr));
	}

	/**
	 * 从文件读取密钥
	 * 
	 * @param fileName
	 * @return
	 * @throws Exception
	 */
	private Object readFromFile(String fileName) throws Exception {
		ObjectInputStream input = new ObjectInputStream(new FileInputStream(fileName));
		Object obj = input.readObject();
		input.close();
		return obj;
	}

	public static String toHexString(byte[] b) {
		StringBuilder sb = new StringBuilder(b.length * 2);
		for (int i = 0; i < b.length; i++) {
			sb.append(HEXCHAR[(b[i] & 0xf0) >>> 4]);
			sb.append(HEXCHAR[b[i] & 0x0f]);
		}
		return sb.toString();
	}

	public static final byte[] toBytes(String s) {
		byte[] bytes;
		bytes = new byte[s.length() / 2];
		for (int i = 0; i < bytes.length; i++) {
			bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
		}
		return bytes;
	}

	private static char[] HEXCHAR = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 

'd', 'e', 'f' };
}