import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import sun.misc.BASE64Decoder; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; /** * 数字签名 * 1:MD5withRSA,:将正文通过MD5数字摘要后,将密文再次通过生成的RSA密钥加密,生成数字签名, * 将明文与密文以及公钥发送给对方,对方拿到私钥/公钥对数字签名进行解密,然后解密后的,与明文经过MD5加密进行比较如果一致则通过 * 2:使用Signature的API来实现MD5withRSA * */ public class MD5withRSA { /** * 使用RSA生成一对钥匙 * * @return * @throws NoSuchAlgorithmException */ public static KeyPair getKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(512);//生成返回带有公钥和私钥的对象 KeyPair generateKeyPair = keyPairGenerator.generateKeyPair(); return generateKeyPair; } /** * 生成私钥 * * @param key * @return */ public static PrivateKey getPrivateKey(KeyPair key) { PrivateKey generatePrivate = null; try { PrivateKey private1 = key.getPrivate(); byte[] encoded = private1.getEncoded(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); KeyFactory factory = KeyFactory.getInstance("RSA"); generatePrivate = factory.generatePrivate(keySpec); } catch (Exception e) { // TODO: handle exception } return generatePrivate; } /** * 私钥加密 * * @param bb * @param key * @return * @throws IllegalBlockSizeException * @throws BadPaddingException */ public static byte[] encrtpyByPrivateKey(byte[] bb, PrivateKey key) throws IllegalBlockSizeException, BadPaddingException { byte[] doFinal = null; try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, key); doFinal = cipher.doFinal(bb); } catch (Exception e) { // TODO: handle exception } return doFinal; } /** * 获取公钥 * * @param keyPair * @return */ public static PublicKey getPublicKey(KeyPair keyPair) { PublicKey publicKey = null; try { PublicKey public1 = keyPair.getPublic(); byte[] encoded = public1.getEncoded(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded); KeyFactory factory = KeyFactory.getInstance("RSA"); publicKey = factory.generatePublic(keySpec); } catch (Exception e) { // TODO: handle exception } return publicKey; } /** * 使用公钥解密 * * @param b * @param key * @return */ public static byte[] decodePublicKey(byte[] b, PublicKey key) { byte[] doFinal = null; try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, key); doFinal = cipher.doFinal(b); } catch (Exception e) { // TODO: handle exception } return doFinal; } //通过MD5加密 public static byte[] encryptMD5(String str) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("MD5"); byte[] digest2 = digest.digest(str.getBytes()); return digest2; } //sign签名 public static byte[] sign(String str, PrivateKey key) throws NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException { byte[] encryptMD5 = encryptMD5(str); byte[] encrtpyByPrivateKey = encrtpyByPrivateKey(encryptMD5, key); return encrtpyByPrivateKey; } //校验 public static boolean verify(String str, byte[] sign, PublicKey key) throws NoSuchAlgorithmException { byte[] encryptMD5 = encryptMD5(str); byte[] decodePublicKey = decodePublicKey(sign, key); String a = new String(encryptMD5); String b = new String(decodePublicKey); if (a.equals(b)) { return true; } else { return false; } } /** * Signature的用法 * 数字签名 * * @param str * @param key * @return * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public static byte[] signMethod(String str, PrivateKey key) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { //初始化 MD5withRSA Signature signature = Signature.getInstance("MD5withRSA"); //使用私钥 signature.initSign(key); //需要签名或校验的数据 signature.update(str.getBytes()); //进行数字签名 return signature.sign(); } /** * 使用getPublicKey得到公钥,返回类型为PublicKey * * @param base64 String to PublicKey * @throws Exception */ public static PublicKey getPublicKey(String key) throws Exception { byte[] keyBytes; keyBytes = (new BASE64Decoder()).decodeBuffer(key); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 转换私钥 * * @param base64 String to PrivateKey * @throws Exception */ public static PrivateKey getPrivateKey(String key) throws Exception { byte[] keyBytes; keyBytes = (new BASE64Decoder()).decodeBuffer(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 数字校验 * * @param str * @param sign * @param key * @return * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public static boolean verifyMethod(String str, byte[] sign, PublicKey key) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(key); signature.update(str.getBytes()); return signature.verify(sign); } public static void main(String[] args) throws NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, SignatureException { String str = "司法改革晚上v的方法的官方"; System.out.println("待加密的明文:" + str); byte[] encryptMD5 = encryptMD5(str); System.out.println("MD5加密后:" + encryptMD5); //获取钥匙对 KeyPair keyPair = getKeyPair(); //获取公钥 PublicKey publicKey = getPublicKey(keyPair); //公钥转成字符串 String pk = Base64.encodeBase64String(publicKey.getEncoded()); System.out.println("获取公钥字符串"+ pk); //System.out.println("另一种加密获取字符串"+ new String(Hex.encodeHex(publicKey.getEncoded()))); //获取私钥 PrivateKey privateKey = getPrivateKey(keyPair); //sign签名 byte[] sign = sign(str, privateKey); boolean verify = verify(str, sign, publicKey); System.out.println("是否一致" + verify); byte[] encrtpyByPrivateKey = encrtpyByPrivateKey(encryptMD5, privateKey); System.out.println("使用私钥加密过后:" + encrtpyByPrivateKey); byte[] decodePublicKey = decodePublicKey(encrtpyByPrivateKey, publicKey); System.out.println("使用公钥解密过后:" + decodePublicKey); System.out.print("判断解密过后,是否一致"); System.out.println(new String(decodePublicKey).equals(new String(encryptMD5))); /********************基于SignatureAPI签名*************************************/ String signStr = "的方法十分士大夫"; byte[] signMethod = signMethod(signStr, privateKey); boolean verifyMethod = verifyMethod(signStr, signMethod, publicKey); System.out.println("使用SignatureAPI 数字签名是否一致:" + verifyMethod); } }
数字签名算法中MD5withRSA
最新推荐文章于 2021-02-21 12:53:49 发布