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' }; }