• base64,AES,RSA,SHA和MD5等加密方式(jdk)


    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.IOException;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    public class TestSecu {
        public static void main(String[] args) {
            try {
                //base64();
                //aes();
                //sm();
                rsa();
                //sing();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * RSA加密
         * 非对称加密,加密密钥分为公钥和私钥。可以使用公钥加密私钥解密,也可以使用私钥加密公钥解密
         * 数字签名是带有密钥(公钥、私钥)的消息摘要算法。主要作用是验证数据的完整性、认证数据来源、抗否认。在数字签名的实现中我们使用私钥签名、公钥验证。常用的数字签名算法包括RSA、DSA、ECDSA。
         */
        static void rsa() throws Exception {
            String src = "hello rsa";
    
            //1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);//密钥长度为64的整数倍,最大是65536
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            byte[] pk =  rsaPublicKey.getEncoded();
            byte[] sk = rsaPrivateKey.getEncoded();
            System.out.println("RSA公钥:" + parseByte2HexStr(pk));
            System.out.println("RSA私钥:" + parseByte2HexStr(sk));//可以将其保存到本地文件中
    
            //2.1私钥加密,公钥解密【加密】
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] result = cipher.doFinal(src.getBytes());
            System.out.println("RSA私钥加密:" + parseByte2HexStr(result));
    
            //2.2私钥加密,公钥解密【解密】
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            result = cipher.doFinal(result);
            System.out.println("RSA公钥解密:" + new String(result));
    
            //3.1公钥加密,私钥解密【加密】
            x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            result = cipher.doFinal(src.getBytes());
            System.out.println("RSA公钥加密:" + parseByte2HexStr(result));
    
            //3.2公约加密,私钥解密【解密】
            pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            result = cipher.doFinal(result);
            System.out.println("RSA私钥解密:" + new String(result));
    
        }
    
        /**
         * 数字签名-rsa
         * 数字签名是带有密钥(公钥、私钥)的消息摘要算法。主要作用是验证数据的完整性、认证数据来源、抗否认。在数字签名的实现中我们使用私钥签名、公钥验证。常用的数字签名算法包括RSA、DSA、ECDSA。n
         */
        static void sing() throws Exception {
            String src = "hello rsa";
    
            //1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
    
            //2.执行数字签名【私钥签名】
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("MD5WithRSA");
            signature.initSign(privateKey);
            signature.update(src.getBytes());
            byte[] result = signature.sign();
            System.out.println("RSA签名:" + parseByte2HexStr(result));
    
            //3.验证签名【公钥验证】
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            signature = Signature.getInstance("MD5WithRSA");
            signature.initVerify(publicKey);
            signature.update(src.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("数字签名是否有效?" + bool);
        }
    
        /**
         * Base64
         * Base64并不是一种加密/解密算法,而是一种编码方式。Base64不生成密钥,通过Base64编码后的密文就可以直接“翻译”为明文,但是可以通过向明文中添加混淆字符来达到加密的效果。
         * 注意,都是基于字节的
         */
        static void base64() throws IOException {
            String src = "www.xxx.com?title=你好";
    
            //加密
            BASE64Encoder encoder = new BASE64Encoder();
            String encode = encoder.encode(src.getBytes());
            System.out.println("加密后:"+encode);
    
            //解密
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] decode = decoder.decodeBuffer(encode);
            System.out.println("解密后:"+new String(decode));
        }
    
        /**
         * AES
         * AES是现在对称加密算法中最流行的算法之一。加密密钥和解密密钥相同,加密运算和解密运算互为逆运算。是一种初等的加密算法。主要的算法有DES(3DES)、AES、PBE、IDEA。
         */
        static void aes() throws Exception {
            String src = "name=张三";//加密内容
            String pkey = "123";//秘钥
    
            //配置--加密与解密公用的
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(pkey.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
    
            //加密
            byte[] byteContent = src.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化加密器
            byte[] result = cipher.doFinal(byteContent);
            String p = parseByte2HexStr(result);//不可直接转成字符串
            System.out.println("密文:" + p);
    
            //解密
            cipher.init(Cipher.DECRYPT_MODE, key);// 初始化解密器
            byte[] decryptFrom = parseHexStr2Byte(p);
            byte[] result1 = cipher.doFinal(decryptFrom);
            System.out.println("原文:" + new String(result1));
        }
    
    
        /**
         * SHA与MD5
         * 不可逆的加密方式,是为了防止消息在传输过程中的篡改。验证信息等。
         */
        static void sm() throws Exception {
            String src = "abcd";
    
            //加密
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");// 构建加密类型/SHA-512
            messageDigest.update(src.getBytes());// 传入要加密的字符串
            byte[] b = messageDigest.digest();
            String p = parseByte2HexStr(b);
            System.out.println("加密后"+p);
    
        }
    
        /**
         * 二进制转换成16进制,加密后的字节数组不能直接转换为字符串
         */
        static String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
        /**
         * 16进制转换成二进制
         */
        static byte[] parseHexStr2Byte(String hexStr) {
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    
    }

    在这里如果直接把md5Bye转换为String的话会发现是一堆乱码,这是因为加密是将字节按照一定的规则进行了转换,转换后出什么样的怪字符都是正常的。因此一般的做法是将加密后的byte数组转换为十六进制的字符串

    通过上面的代码可以看出MD5和SHA算法都是通过MessageDigest 来实现的,通过jdk的官方文档看以看出MessageDigest.getInstance(“SHA-1”);支持的参数有MD5、SHA-1和SHA-256,我试过如果输入SHA也是可以的,返回的结果和SHA-1是一致的

  • 相关阅读:
    【js】栈方法和队列方法
    adb devices 不能连接设备 could not install *smartsocket* listener
    mysql无法启动服务,错误1067
    Sql Server存储过程详解
    ef not in
    checkbox多选框取值
    Linq 常用操作(增删改)
    二进制与图片相互转换
    jQuery 二级联动
    百度地图API功能
  • 原文地址:https://www.cnblogs.com/h-c-g/p/10670019.html
Copyright © 2020-2023  润新知