23,407
社区成员
发帖
与我相关
我的任务
分享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);
}
}