日期:2014-05-20 浏览次数:20813 次
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.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class Test { private final static char[] HEX = "0123456789abcdef".toCharArray(); public static void main(String[] args) throws Exception { // 生成密钥对 KeyPair pair = generateRandomRSAKeyPair(1024); // 获得私钥 PrivateKey privateKey = pair.getPrivate(); // 获得公钥 PublicKey publicKey = pair.getPublic(); // 获取公私钥对的字节数组,便于保存起来 // 获取二进制格式的私钥 byte[] privateKeyEnc = privateKey.getEncoded(); // 获取二进制格式的公钥 byte[] publicKeyEnc = publicKey.getEncoded(); System.out.println("private key: " + toHex(privateKeyEnc)); System.out.println(" public key: " + toHex(publicKeyEnc)); // 从字节数组中恢复公私钥对 KeyPair restorePair = restoreKeyPair(privateKeyEnc, publicKeyEnc, "RSA"); System.out.println("private key: " + toHex(restorePair.getPrivate().getEncoded())); System.out.println(" public key: " + toHex(restorePair.getPublic().getEncoded())); String str = "abcdefg"; // 数字签名 byte[] sign = sign(str, restorePair.getPrivate(), "MD5WithRSA"); System.out.println("签名值: " + toHex(sign)); // 验证签名 boolean verifyResult = verify(str, sign, restorePair.getPublic(), "MD5WithRSA"); System.out.println("签名验证结果: " + verifyResult); } /** * <p>还原公私钥对</p> * * @param privateKeyEnc 私钥编码字节 * @param publicKeyEnc 公钥编码字节 * @param algorithm 非对称加密算法 * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static KeyPair restoreKeyPair(byte[] privateKeyEnc, byte[] publicKeyEnc, String algorithm) throws NoSuchAlgorithmException, InvalidKeySpecException { return new KeyPair(restorePublicKey(publicKeyEnc, algorithm), restorePrivateKey(privateKeyEnc, algorithm)); } /** * <p>通过字符数组还原私钥</p> * * @param privateKeyEnc 私钥的字节 * @param algorithm 非对称加密算法 * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PrivateKey restorePrivateKey(byte[] privateKeyEnc, String algorithm) throws NoSuchAlgorithmException, InvalidKeySpecException { KeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyEnc); KeyFactory factory = KeyFactory.getInstance(algorithm); return factory.generatePrivate(keySpec); } /** * <p>通过字符数组还原公钥</p> * * @param privateKeyEnc 公钥的字节 * @param algorithm 非对称加密算法 * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PublicKey restorePublicKey(byte[] publicKeyEnc, String algorithm) throws NoSuchAlgorithmException, InvalidKeySpecException { KeySpec keySpec = new X509EncodedKeySpec(publicKeyEnc); KeyFactory factory = KeyFactory.getInstance(algorithm); return factory.generatePublic(keySpec); } /** * <p>生成随机 RSA 密钥对</p> * @param keySize RSA 密钥对长度 * @return * @throws NoSuchAlgorithmException */ public static KeyPair generateRandomRSAKeyPair(int keySize) throws NoSuchAlgorithmException { KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); gen.initialize(keySize); return gen.generateKeyPair(); } /** * <p>数字签名</p> * * @param str 需要签名的字符串 * @param privateKey 签名私钥 * @param signatureAlgorithm 数字签名算法 * @return * @throws Exception */ public static byte[] sign(String str, PrivateKey privateKey, String signatureAlgorithm) throws Exception { Signature signature = Signature.getInstance(signatureAlgorithm); signature.initSign(privateKey); signature.update(str.getBytes("UTF-8")); return signature.sign(); } /** * <p>验证签名</p> * * @param str 需要验证签名的字符串 * @param sign 签名数据 * @param publicKey 验证签名的公钥 * @param signatureAlgorithm 数字签名算法 * @return */ public static boolean verify(String str, byte[] sign, PublicKey publicKey, String signatureAlgorithm) { try { Signature signature = Signature.getInstance(signatureAlgorithm); signature.initVerify(publicKey); signature.update(str.getBytes("UTF-8")); return signature.verify(sign); } catch (Exception e) { e.printStackTrace(); return false; } } /** * <p>将字节转换成为 HEX 字符</p> * * @param bys * @return */ public static String toHex(byte[] bys) { char[] chs = new char[bys.length * 2]; for (int i = 0, k = 0; i < bys.length; i++) { chs[k++] = HEX[(bys[i] >> 4) & 0xf]; chs[k++] = HEX[bys[i] & 0xf]; } return new String(chs); } }