前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >加密-解密详解

加密-解密详解

作者头像
用户5927264
发布2020-07-30 22:06:37
2.7K0
发布2020-07-30 22:06:37
举报
文章被收录于专栏:OSChinaOSChina

参考视频: https://www.bilibili.com/video/BV1tz4y197hm

代码语言:javascript
复制
package com.shi.encrypt.ascii;

import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * Ascii 编码测试
 *
 * @author shiye
 * @create 2020-07-27 17:25
 */
public class AsciiDemo {

    //每个字节数据再ASCII中都有一个数字对应
    @Test
    public void test1() {
//        char a = 'A';
//        int b = a;
//        //65
//        System.out.println(b);

        String a = "AaZ";
        char[] chars = a.toCharArray();
        for (char aChar : chars) {
            int asciiA = aChar;
            System.out.println(asciiA);
        }
    }

    /**
     * 凯撒加密
     * 就是移位法加密
     * 破解方式:使用概率分析法:默认最高是e
     */
    @Test
    public void kaiserTest() {
        //定义原文
        String input = "Hello World";
        //向右移动3位
        int key = 3;
        char[] chars = input.toCharArray();

        //装新生成的数字
        StringBuilder sb = new StringBuilder();
        for (char aChar : chars) {
            int b = aChar;
            b = b + key;
            char bChar = (char) b;
            sb.append(bChar);
        }
        //加密后的密文为====Khoor#Zruog
        System.out.println("加密后的密文为====" + sb.toString());

        System.out.println("====================================");

        char[] charArray = sb.toString().toCharArray();
        StringBuilder tempA = new StringBuilder();
        for (char charA : charArray) {
            int c = charA;
            c = c - key;
            char charC = (char) c;
            tempA.append(charC);
        }
        //解密后的明文====Hello World
        System.out.println("解密后的明文====" + tempA);
    }

    /**
     * 根据编码格式不一样,对应的字节也不一样
     * 如果是UTF-8: 一个中文对应的是三个字节: -26 -106 -67
     * 如果是GBK: 一个中文对应俩个字节:-54 -87
     * 如果是英文就无所谓编码格式
     *
     * @throws Exception
     */
    @Test
    public void test2() throws Exception {
        String a = "施";
        byte[] aBytes = a.getBytes("GBK");
        for (byte abyte : aBytes) {
            System.out.println(abyte);
        }
    }

    /**
     * 对称加密:DES加密 密钥必须是8位
     * 如果是使用AES进行加密的,需要密码是16位
     * 需要配合base64使用
     * <p>
     * 加密算法/加密模式/填充模式
     * DES
     * DES/ECB/PKCS5Padding  默认方式
     * DES/ECB/NoPadding
     * DES/CBC/PKCS5Padding
     * DES/CBC/NoPadding
     * <p>
     * AES
     * AES/ECB/PKCS5Padding  默认方式
     * AES/ECB/NoPadding
     * AES/CBC/PKCS5Padding
     * AES/CBC/NoPadding
     */
    @Test
    public void testDES() throws Exception {
        //原文
        String input = "施爷";
        System.out.println("明文==" + input);

        //定义key,密钥必须是8位
        String key = "12345678";
        //算法
        String transformation = "DES";
//        String transformation = "DES/ECB/PKCS5Padding";
//        String transformation = "DES/CBC/PKCS5Padding";
        //再使用CBC加密模式的时候需要使用该iv变量,IV必须是8个字节
//        IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
        //如果是使用AES进行加密的,需要密码是16位
//        String transformation = "AES";
        //创建加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        //加密类型
        String algorithm = "DES";
        /**
         * 创建加密规则
         * 第一参数: 表示key的字节
         * 第二个参数:表示加密的类型
         */
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);

        /**
         * 进行加密初始化
         * 第一个表示模式,加密模式,解密模式
         * 第二个参数表示:加密的规则
         */
//        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec,iv);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

        /**
         * 调用加密方法
         * 参数表示原文的字节数组
         */
        byte[] bytes = cipher.doFinal(input.getBytes());

//        for (byte aByte : bytes) {
//            System.out.println(aByte);
//        }
//        System.out.println(new String(bytes));//a&f�B
        /**
         * 需要配合base64进行加密,否则会出现乱码
         * 如果字节不够3个使用=号补齐
         */
        String encode = Base64.encode(bytes);
        System.out.println("加密==" + encode);//DmEmZoQXQhI=


        System.out.println("***************解密*******************");
        //创建解密对象
        Cipher cipher1 = Cipher.getInstance(transformation);
        /**
         * 创建解密规则
         * 第一参数: 表示key的字节
         * 第二个参数:表示解密的类型
         */
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        //解密对象初始化
        cipher1.init(Cipher.DECRYPT_MODE, sks);
        //解码
        byte[] decode = Base64.decode(encode);
        //解密
        byte[] bytes1 = cipher1.doFinal(decode);
        System.out.println("解密==" + new String(bytes1));
    }

    /**
     * Base64位测试,
     * 原理:三个字节位一组,总共24位,把24位拆成4组,每组6个字节,高位补齐2个字节0
     * 根据base64位编码表进行编排,生成信的字符串,
     * 不足三个字节的使用=号补齐
     */
    @Test
    public void base64Test() throws Exception {
        System.out.println(Base64.encode("1".getBytes()));//MQ==

        System.out.println(Base64.encode("12".getBytes()));//MTI=

        System.out.println(Base64.encode("123".getBytes()));//MTIz
        //汉字utf-8编码,就是三个字节
        System.out.println(Base64.encode("施".getBytes()));//5pa9
        //如果是使用GBK编码就是俩个字节
        System.out.println(Base64.encode("施".getBytes("GBK")));//yqk=
    }

    /**
     * 消息摘要/数字摘要
     * 算法:MD5
     * SHA-1
     * SHA-256
     * SHA-512
     */
    @Test
    public void messageDigest() throws NoSuchAlgorithmException {
        //原文
        String input = "施爷";
        //算法
        String algorithm = "MD5";
        //创建消息摘要对象
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        //执行消息摘要进行加密
        byte[] digest = messageDigest.digest(input.getBytes());
        //使用base64进行转码
        System.out.println("Base64编码后的值为:" + Base64.encode(digest));//AsK7qXM7045eqFc2jILPBw==

        //===================================
        //直接转成16进制输出结果
        for (byte b : digest) {
            //把密文转成16进制
            String hexString = Integer.toHexString(b & 0Xff);
            if (hexString.length() == 1) {
                hexString = "0" + hexString;
            }
            System.out.print(hexString);
        }
    }


    /**
     * 非对称加密:RSA   ECC
     * RSA 加密算法
     * 想单独生成 PrivateKey 对象 可以使用 KeyFactory
     * PublicKey 同上
     */
    @Test
    public void RSAtest() throws Exception {
        String input = "施爷";
        //使用的加密算法
        String algorithm = "RSA";
        //KeyPairGenerator:密钥对生成器对象
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        //生成密钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        //===私钥
        PrivateKey aPrivate = keyPair.getPrivate();
        byte[] encoded = aPrivate.getEncoded();
        String privateKey = Base64.encode(encoded);
        System.out.println("私钥为==" + privateKey);
        FileUtils.writeStringToFile(new File("privateKey.pub"), privateKey, Charset.forName("UTF-8"));

        //===公钥
        PublicKey aPublic = keyPair.getPublic();
        byte[] encoded1 = aPublic.getEncoded();
        String publicKey = Base64.encode(encoded1);
        System.out.println("公钥为==" + publicKey);
        FileUtils.writeStringToFile(new File("publicKey.pri"), publicKey, Charset.forName("UTF-8"));

        /*======================使用私钥加密======================*/
        //创建加密对象
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, aPrivate);
        byte[] doFinal = cipher.doFinal(input.getBytes());
        String encode = Base64.encode(doFinal);
        System.out.println("加密后的值为===" + encode);

        /*======================使用公钥解密======================*/
        Cipher cipher2 = Cipher.getInstance(algorithm);
        cipher2.init(Cipher.DECRYPT_MODE, aPublic);
        byte[] doFinal2 = cipher2.doFinal(Base64.decode(encode));
        System.out.println("解密后的值为===" + new String(doFinal2));
    }


    /**
     * 数字证书
     */
    @Test
    public void test22() throws Exception {
        String input = "施爷";
        //使用的加密算法
        String algorithm = "RSA";
        String privateKeyStr = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKdzMj8aAS28BIH6qGIB7+O0z6bu\n" +
                "ujjYJlBhFbtt+Ai9Mm90+rQq7cnc0g7FGAGsBvtfoF+BEKLUNMl6LkGsXM8Sz42P+UWQGslhWYqW\n" +
                "Wo4f7PyCVNlLEcsRgt43JnFQ1yUbtttMKHs8whYcAgFaIyEdGw4h8aGffEVA0VxkshCHAgMBAAEC\n" +
                "gYBOyOmEPQT+8q6gRUJCUqz+0wy8eygNJM3qFbO26we/fN0lCcIHUQduacI/hsZDyx/B1/1J0hz0\n" +
                "r6lifmUTKzjCxKvxpvQFa0iM3njqNX/z+tOpK9RX+awIW7syACbZG4ZCwCPSflB/3uoBYHT4oY5/\n" +
                "WumWX1Berb8WUU1jHZ8SYQJBAOsbXsh4IubAdzmerYoKh5RWEwxF6nHd58XRQq6DnKWvRN/LNUsF\n" +
                "fTDodFkhpC2VFSMxaNSelboYRvXON59rWzECQQC2VKVgu8moqfrS11fEwQ6Iq4sG+mt08/GT2BUZ\n" +
                "yz5z6vXCK+cTjRf4hgR4oGC01/ZlL8OhiUsgA8cprmHoiMk3AkA5/1N/cptxfxMqRKmcvwI5Jo6m\n" +
                "XWz7T/mIBBpGALOY78a2ymNIMX9znDRvdGwSzo8bUmoA4WogMTL4GjoAerRRAkAksXI6vm/97n9Y\n" +
                "0ReLtCJ9pLAs7laTycgTLchJUZq271EYC4fManepfycFM5liq5edk3g2WQ/yWHBLVhnEF0sPAkA7\n" +
                "B/cOKB4Z0HkUSMEL0P8OT7N/afZMzv/KjpTAMKUfrgNptSTG5y2TcGEv4Bktj/+4SAegnVKF98oM\n" +
                "+Vh4i9lw";
        String publiceKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnczI/GgEtvASB+qhiAe/jtM+m7ro42CZQYRW7\n" +
                "bfgIvTJvdPq0Ku3J3NIOxRgBrAb7X6BfgRCi1DTJei5BrFzPEs+Nj/lFkBrJYVmKllqOH+z8glTZ\n" +
                "SxHLEYLeNyZxUNclG7bbTCh7PMIWHAIBWiMhHRsOIfGhn3xFQNFcZLIQhwIDAQAB";


        //创建key工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        /*===========================生成私钥对象===========================*/
        //私钥规则
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
//        System.out.println("私钥对象=" + privateKey);

        /*===========================生成公钥对象===========================*/
        //公钥规则
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publiceKeyStr));
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
//        System.out.println("公钥对象=" + publicKey);


        /*------------------------生成数字签名------------------------------*/
        //获取签名对象
        Signature signature = Signature.getInstance("sha256withrsa");
        //初始化签名
        signature.initSign(privateKey);
        //传入原文
        signature.update(input.getBytes());
        //开始签名
        byte[] sign = signature.sign();
        String encode_sign = Base64.encode(sign);
        System.out.println("生成的签名为=" + encode_sign);


        /*------------------------校验数字签名------------------------------*/
        //获取签名对象
        Signature signature2 = Signature.getInstance("sha256withrsa");
        //初始化校验
        signature2.initVerify(publicKey);
        //传入原文
        signature2.update(input.getBytes());
        //开始和签名对比,校验签名
        boolean verify = signature2.verify(Base64.decode(encode_sign));
        System.out.println("验签的结果为=" + verify);
    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档