精华内容
下载资源
问答
  • 一、加密的方式 1. 对称加密 1. 简介 2. 优缺点: 3. 经典对称加密: ...2. 前端利用公钥数据进行加密 3. 后端利用私钥数据进行解密 2. 对称加密 AES 3. 单向散列加密 MD5 SHA1 三、加密算法比较

    一、加密的方式

    1. 对称加密

    1. 简介

    加密和解密使用同一个密钥。

    image-20201215212008616

    2. 优缺点:

    • 算法公开,计算量小,加密速度快,加密效率高
    • 双方使用相同的钥匙,安全性得不到保证
    • 秘钥管理比较难,不适合互联网,一般用于内部系统

    3. 经典对称加密:

    1. DES(Data Encryption Standard):数据加密标准(现在用的比较少,因为它的加密强度不够,能够暴力破解)
    2. 3DES:原理和DES几乎是一样的,只是使用3个密钥,对相同的数据执行三次加密,增强加密强度。(缺点:要维护3个密钥,大大增加了维护成本)
    3. AES(Advanced Encryption Standard):高级加密标准,目前美国国家安全局使用的,苹果的钥匙串访问采用的就AES加密。是现在公认的最安全的加密方式,是对称密钥加密中最流行的算法。
    DES

    DES(Data Encryption Standard)是目前最为流行的加密算法之一。DES是对称的,也就是说它使用同一个密钥来加密和解密数据。

    原理

    DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行"异或"运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。

    不过,DES已可破解,所以针对保密级别特别高的数据推荐使用非对称加密算法。

    image-20201215204800639

    优缺点

    AES

    image-20201215213723491

    属性

    1. 秘钥

    用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。

    1. AES加密函数

    设AES加密函数为E,则 C = E(K, P),其中P为明文,K为密钥,C为密文。也就是说,把明文P和密钥K作为加密函数的参数输入,则加密函数E会输出密文C。

    1. AES解密函数

    设AES解密函数为D,则 P = D(K, C),其中C为密文,K为密钥,P为明文。也就是说,把密文C和密钥K作为解密函数的参数输入,则解密函数会输出明文P。

    原理

    基于原理逐步实现AES加密算法


    2. 非对称加密

    1. 用法

    (1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

    (2)甲方获取乙方的公钥,然后用它对信息加密。

    (3)乙方得到加密后的信息,用私钥解密。

    2. 典型非对称加密——RSA

    ​ RSA非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

    3. 实现原理

    RSA算法原理

    4. 特点

    • 算法强度复杂,安全性依赖于算法与密钥。
    • 加密解密速度慢。适合 小数据量 加解密或数据签名
    • 密钥容易管理

    5. 对比

    与对称加密算法的对比:

    • 对称加密只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。
    • 非对称加密有两种密钥,其中一个是公开的。

    6. RSA应用场景:

    由于RSA算法的加密解密速度要比对称算法速度慢很多,在实际应用中,通常采取
    数据本身的加密和解密使用对称加密算法(AES)。
    用RSA算法加密并传输对称算法所需的密钥。

    image-20201215214125330

    3. 单向散列加密

    不可逆,只能加密,不能解密

    单向散列加密是指通过对不同输入长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出进行计算从而获得输入信息。

    利用单向散列加密的这个特性,可以进行密码加密保存,即用户注册时输入的密码不直接保存到数据库,而是对密码进行单向散列加密,将密文存入数据库,用户登录时,进行密码验证,同样计算得到输入密码的密文,并和数据库中的密文比较,如果一致,则密码验证成功。为了加强单向散列计算的安全性,还会给散列算法加点salt,salt相当于加密的密钥,增加破解的难度。常用的单向散列算法有MD5、SHA等。

    特点

    • 算法强度复杂
    • 无秘钥

    二、加密算法实现

    1. 非对称加密(RSA)

    前端公钥加密,后端私钥解密。

    image-20201215213430529

    1. 生成秘钥

    利用在线生成秘钥工具生成非对称加密公钥私钥对

    在线生成非对称公钥私钥对

    2. 前端对利用公钥对数据进行加密

    工具类

    import JSEncrypt from 'jsencrypt/bin/jsencrypt'
    
    // 密钥对生成 http://web.chacuo.net/netrsakeypair
    
    const publicKey = '...'
    
    const privateKey = '...'
    
    // 加密
    export function encrypt(txt) {
      const encryptor = new JSEncrypt()
      encryptor.setPublicKey(publicKey) // 设置公钥
      return encryptor.encrypt(txt) // 对需要加密的数据进行加密
    }
    
    // 解密
    export function decrypt(txt) {
      const encryptor = new JSEncrypt()
      encryptor.setPrivateKey(privateKey)
      return encryptor.decrypt(txt)
    }
    
    

    使用公钥加密

    user.password = encrypt(user.password)
    

    3. 后端利用私钥对数据进行解密

    工具类

    package com.advance.utils;
    
    import org.apache.commons.codec.binary.Base64;
    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    /**
     * description Rsa 工具类,公钥私钥生成,加解密
     * @author https://www.cnblogs.com/nihaorz/p/10690643.html
     * @date 2020-12-15
     **/
    public class RsaUtils {
    
        private static final String SRC = "123456";
    
        public static void main(String[] args) throws Exception {
            System.out.println("\n");
            RsaKeyPair keyPair = generateKeyPair();
            System.out.println("公钥:" + keyPair.getPublicKey());
            System.out.println("私钥:" + keyPair.getPrivateKey());
            System.out.println("\n");
            test1(keyPair);
            System.out.println("\n");
            test2(keyPair);
            System.out.println("\n");
        }
    
        /**
         * 公钥加密私钥解密
         */
        private static void test1(RsaKeyPair keyPair) throws Exception {
            System.out.println("***************** 公钥加密私钥解密开始 *****************");
            String text1 = encryptByPublicKey(keyPair.getPublicKey(), RsaUtils.SRC);
            String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1);
            System.out.println("加密前:" + RsaUtils.SRC);
            System.out.println("加密后:" + text1);
            System.out.println("解密后:" + text2);
            if (RsaUtils.SRC.equals(text2)) {
                System.out.println("解密字符串和原始字符串一致,解密成功");
            } else {
                System.out.println("解密字符串和原始字符串不一致,解密失败");
            }
            System.out.println("***************** 公钥加密私钥解密结束 *****************");
        }
    
        /**
         * 私钥加密公钥解密
         * @throws Exception /
         */
        private static void test2(RsaKeyPair keyPair) throws Exception {
            System.out.println("***************** 私钥加密公钥解密开始 *****************");
            String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), RsaUtils.SRC);
            String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1);
            System.out.println("加密前:" + RsaUtils.SRC);
            System.out.println("加密后:" + text1);
            System.out.println("解密后:" + text2);
            if (RsaUtils.SRC.equals(text2)) {
                System.out.println("解密字符串和原始字符串一致,解密成功");
            } else {
                System.out.println("解密字符串和原始字符串不一致,解密失败");
            }
            System.out.println("***************** 私钥加密公钥解密结束 *****************");
        }
    
        /**
         * 公钥解密
         *
         * @param publicKeyText 公钥
         * @param text 待解密的信息
         * @return /
         * @throws Exception /
         */
        public static String decryptByPublicKey(String publicKeyText, String text) throws Exception {
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] result = cipher.doFinal(Base64.decodeBase64(text));
            return new String(result);
        }
    
        /**
         * 私钥加密
         *
         * @param privateKeyText 私钥
         * @param text 待加密的信息
         * @return /
         * @throws Exception /
         */
        public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception {
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
            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(text.getBytes());
            return Base64.encodeBase64String(result);
        }
    
        /**
         * 私钥解密
         *
         * @param privateKeyText 私钥
         * @param text 待解密的文本
         * @return /
         * @throws Exception /
         */
        public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] result = cipher.doFinal(Base64.decodeBase64(text));
            return new String(result);
        }
    
        /**
         * 公钥加密
         *
         * @param publicKeyText 公钥
         * @param text 待加密的文本
         * @return /
         */
        public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
            X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] result = cipher.doFinal(text.getBytes());
            return Base64.encodeBase64String(result);
        }
    
        /**
         * 构建RSA密钥对
         *
         * @return /
         * @throws NoSuchAlgorithmException /
         */
        public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
            String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
            return new RsaKeyPair(publicKeyString, privateKeyString);
        }
    
    
        /**
         * RSA密钥对对象
         */
        public static class RsaKeyPair {
    
            private final String publicKey;
            private final String privateKey;
    
            public RsaKeyPair(String publicKey, String privateKey) {
                this.publicKey = publicKey;
                this.privateKey = privateKey;
            }
    
            public String getPublicKey() {
                return publicKey;
            }
    
            public String getPrivateKey() {
                return privateKey;
            }
    
        }
    }
    
    

    使用私钥解密

    String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, user.getPassword());
    

    2. 对称加密

    java实现AES加密解密算法

    AES

    package com.marchosft.security;
    
    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.UnsupportedEncodingException;
    import java.security.SecureRandom;
    import java.util.Base64;
    
    /**
     * Description:java实现AES加密解密算法 AES加密结果用Base64再做加密处理
     * Date: 2020/12/16 10:59
     **/
    
    public class AesUtil {
        private static final String DEFAULT_KEY = "12345678";
        static final Base64.Decoder DECODER = Base64.getDecoder();
        static final Base64.Encoder ENCODER = Base64.getEncoder();
        static final String CHARSET = "utf-8";
        static final String AES = "AES";
    
        /**
         * 先AES加密,再Base64加密
         *
         * @param content 待加密的内容
         * @return /
         */
        public static String encodeBase64(String content) {
            //AES加密
            String encode = encode(content);
            //加密失败返回空
            if (encode == null) {
                return null;
            }
    
            try {
                //Base64加密
                return ENCODER.encodeToString(encode.getBytes(CHARSET));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 先Base64解密,再AES解密
         *
         * @param content 待解密的内容
         * @return /
         */
        public static String decodeBase64(String content) {
            try {
                //Base64解密
                String s = new String(DECODER.decode(content), CHARSET);
                //AES解密
                return decode(s);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            //解密失败返回空
            return null;
        }
    
        /**
         * AES加密
         *
         * @param content 待加密的内容
         * @return /
         */
        public static String encode(String content) {
            return encode(DEFAULT_KEY, content);
        }
    
        /**
         * AES解密
         *
         * @param content 待解密的内容
         * @return /
         */
        public static String decode(String content) {
            return decode(DEFAULT_KEY, content);
        }
    
        /**
         * AES加密
         * 1.构造密钥生成器
         * 2.根据ecnodeRules规则初始化密钥生成器
         * 3.产生密钥
         * 4.创建和初始化密码器
         * 5.内容加密
         * 6.返回字符串
         */
        public static String encode(String encodeRules, String content) {
            try {
                //1.构造密钥生成器,指定为AES算法,不区分大小写
                KeyGenerator keygen = KeyGenerator.getInstance(AES);
                //2.根据ecnodeRules规则初始化密钥生成器
                //生成一个128位的随机源,根据传入的字节数组
                SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
                random.setSeed(encodeRules.getBytes());
                keygen.init(128, random);
                //3.产生原始对称密钥
                SecretKey originalKey = keygen.generateKey();
                // 4.获得原始对称密钥的字节数组
                byte[] raw = originalKey.getEncoded();
                //5.根据字节数组生成AES密钥
                SecretKey key = new SecretKeySpec(raw, AES);
                //6.根据指定算法AES自成密码器
                Cipher cipher = Cipher.getInstance(AES);
                //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
                cipher.init(Cipher.ENCRYPT_MODE, key);
                //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
                byte[] byteEncode = content.getBytes(CHARSET);
                //9.根据密码器的初始化方式--加密:将数据加密
                byte[] byteAes = cipher.doFinal(byteEncode);
                //10.将加密后的数据转换为字符串
                //这里用Base64Encoder中会找不到包
                //解决办法:
                //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
                //11.将字符串返回
                return new String(new BASE64Encoder().encode(byteAes));
            } catch (Exception e) {
                e.printStackTrace();
            }
            //加密失败返回空
            return null;
        }
    
        /**
         * AES解密
         * 解密过程:
         * 1.同加密1-4步
         * 2.将加密后的字符串反纺成byte[]数组
         * 3.将加密内容解密
         */
        public static String decode(String encodeRules, String content) {
            try {
                //1.构造密钥生成器,指定为AES算法,不区分大小写
                KeyGenerator keygen = KeyGenerator.getInstance(AES);
                //2.根据ecnodeRules规则初始化密钥生成器
                //生成一个128位的随机源,根据传入的字节数组
    //            keygen.init(128, new SecureRandom(encodeRules.getBytes()));
                SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
                random.setSeed(encodeRules.getBytes());
                keygen.init(128, random);
                //3.产生原始对称密钥
                SecretKey originalKey = keygen.generateKey();
                //4.获得原始对称密钥的字节数组
                byte[] raw = originalKey.getEncoded();
                //5.根据字节数组生成AES密钥
                SecretKey key = new SecretKeySpec(raw, AES);
                //6.根据指定算法AES自成密码器
                Cipher cipher = Cipher.getInstance(AES);
                //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
                cipher.init(Cipher.DECRYPT_MODE, key);
                //8.将加密并编码后的内容解码成字节数组
                byte[] byteContent = new BASE64Decoder().decodeBuffer(content);
                /*
                 * 解密
                 */
                byte[] byteDecode = cipher.doFinal(byteContent);
                return new String(byteDecode, CHARSET);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //解密失败返回空
            return null;
        }
    
        public static void main(String[] args) {
            String a = "1236";
            String s = encodeBase64(a);
            System.out.println(s);
            String s1 = decodeBase64(s);
            System.out.println(s1);
        }
    }
    
    

    3. 单向散列加密

    MD5

    public static final byte[] computeMD5(byte[] content) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            return md5.digest(content);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
    

    SHA1

    public static byte[] computeSHA1(byte[] content) {
        try {
            MessageDigest sha1 = MessageDigest.getInstance("SHA1");
            return sha1.digest(content);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
    

    三、加密算法比较

    1、散列算法比较

    名称 安全性 速度
    SHA-1
    MD5

    2、对称加密算法比较

    名称 密钥名称 运行速度 安全性 资源消耗
    DES 56位 较快
    3DES 112位或168位
    AES 128、192、256位

    3、非对称加密算法比较

    名称 成熟度 安全性 运算速度 资源消耗
    RSA
    ECC
    展开全文
  • 对称加密对称加密

    千次阅读 2019-06-15 20:36:31
    对称加密 ...加密计算量小、速度块,适合大量数据进行加密的场景。(记住这个特点,实际使用是会用到的) 对称加密的两大不足 密钥传输问题:如上所说,由于对称加密加密和解密使用的是同一...

    对称加密

    • 什么是对称加密?
      对称加密就是指,加密和解密使用同一个密钥的加密方式。
    • 对称加密的工作过程
      发送方使用密钥将明文数据加密成密文,然后发送出去,接收方收到密文后,使用同一个密钥将密文解密成明文读取。
    • 对称加密的优点
      加密计算量小、速度块,适合对大量数据进行加密的场景。

    常见的对称加密算法有DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES。

    对称加密的两大不足

    • 密钥传输问题:如上所说,由于对称加密的加密和解密使用的是同一个密钥,所以对称加密的安全性就不仅仅取决于加密算法本身的强度,更取决于密钥是否被安全的保管,因此加密者如何把密钥安全的传递到解密者手里,就成了对称加密面临的关键问题。(比如,我们客户端肯定不能直接存储对称加密的密钥,因为被反编译之后,密钥就泄露了,数据安全性就得不到保障,所以实际中我们一般都是客户端向服务端请求对称加密的密钥,而且密钥还得用非对称加密加密后再传输。)
    • 密钥管理问题:再者随着密钥数量的增多,密钥的管理问题会逐渐显现出来。比如我们在加密用户的信息时,不可能所有用户都用同一个密钥加密解密吧,这样的话,一旦密钥泄漏,就相当于泄露了所有用户的信息,因此需要为每一个用户单独的生成一个密钥并且管理,这样密钥管理的代价也会非常大。
    AES加密

    AES加密算法就是众多对称加密算法中的一种,它的英文全称是Advanced Encryption Standard,翻译过来是高级加密标准,它是用来替代之前的DES加密算法的。
    AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。如AES-128,也就是密钥的长度为128位,加密轮数为10轮。
    在这里插入图片描述
    关于AES加密,详细可参考博客:
    https://blog.csdn.net/gulang03/article/details/81175854

    非对称加密

    与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(public key)和私有密钥(private key)。

    公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

    非对称密钥加密的使用过程:

    • A要向B发送信息,A和B都要产生一对用于加密和解密的公钥和私钥。
    • A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。
    • A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。
    • A将这个消息发给B(已经用B的公钥加密消息)。
    • B收到这个消息后,B用自己的私钥解密A的消息,其他所有收到这个报文的人都无法解密,因为只有B才有B的私钥。
    • 反过来,B向A发送消息也是一样。

    常见的非对称加密算法有:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)。

    总结

    从上面大家应该可以看出对称加密和非对称加密的区别,下面稍微进行一下总结:

    (1) 对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。
    (2) 非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。
    (3) 解决的办法是将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。

    参考:
    1.https://www.jianshu.com/p/3840b344b27c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
    2.https://blog.csdn.net/u013320868/article/details/54090295

    展开全文
  • 对称加密对称加密(一)对称加密(Symmetric Cryptography)对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它...

    对称加密与非对称加密


    (一)对称加密(Symmetric Cryptography

    对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。

    对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off

    2000102日,美国国家标准与技术研究所(NIST--American National Institute of Standards and Technology)选择了Rijndael算法作为新的高级加密标准(AES--Advanced Encryption Standard)。.NET中包含了Rijndael算法,类名叫RijndaelManaged,下面举个例子。

    加密过程:

     


            private string myData = "hello";

            private string myPassword = "OpenSesame";

            private byte[] cipherText;

            private byte[] salt = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0 };

                


            private void mnuSymmetricEncryption_Click(object sender, RoutedEventArgs e)

            {

                var key = new Rfc2898DeriveBytes(myPassword, salt);

                // Encrypt the data.

                var algorithm = new RijndaelManaged();

                algorithm.Key = key.GetBytes(16);

                algorithm.IV = key.GetBytes(16);

                var sourceBytes = new System.Text.UnicodeEncoding().GetBytes(myData);

                using (var sourceStream = new MemoryStream(sourceBytes))

                using (var destinationStream = new MemoryStream())

                using (var crypto = new CryptoStream(sourceStream, algorithm.CreateEncryptor(), CryptoStreamMode.Read))

                {

                    moveBytes(crypto, destinationStream);

                    cipherText = destinationStream.ToArray();

                }

                MessageBox.Show(String.Format("Data:{0}{1}Encrypted and Encoded:{2}", myData, Environment.NewLine, Convert.ToBase64String(cipherText)));

            }

            private void moveBytes(Stream source, Stream dest)

            {

                byte[] bytes = new byte[2048];

                var count = source.Read(bytes, 0, bytes.Length);

                while (0 != count)

                {

                    dest.Write(bytes, 0, count);

                    count = source.Read(bytes, 0, bytes.Length);

                }

            }


     

    解密过程:

     


            private void mnuSymmetricDecryption_Click(object sender, RoutedEventArgs e)

            {

                if (cipherText == null)

                {

                    MessageBox.Show("Encrypt Data First!");

                    return;

                }

                var key = new Rfc2898DeriveBytes(myPassword, salt);

                // Try to decrypt, thus showing it can be round-tripped.

                var algorithm = new RijndaelManaged();

                algorithm.Key = key.GetBytes(16);

                algorithm.IV = key.GetBytes(16);

                using (var sourceStream = new MemoryStream(cipherText))

                using (var destinationStream = new MemoryStream())

                using (var crypto = new CryptoStream(sourceStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read))

                {

                    moveBytes(crypto, destinationStream);

                    var decryptedBytes = destinationStream.ToArray();

                    var decryptedMessage = new UnicodeEncoding().GetString(

                    decryptedBytes);

                    MessageBox.Show(decryptedMessage);

                }

            }


     

    对称加密的一大缺点是密钥的管理与分配,换句话说,如何把密钥发送到需要解密你的消息的人的手里是一个问题。在发送密钥的过程中,密钥有很大的风险会被黑客们拦截。现实中通常的做法是将对称加密的密钥进行非对称加密,然后传送给需要它的人。

     

     

    (二)非对称加密(Asymmetric Cryptography

    非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥。比如,你向银行请求公钥,银行将公钥发给你,你使用公钥对消息加密,那么只有私钥的持有人--银行才能对你的消息解密。与对称加密不同的是,银行不需要将私钥通过网络发送出去,因此安全性大大提高。

    目前最常用的非对称加密算法是RSA算法,是Rivest, Shamir, Adleman1978年发明,他们那时都是在MIT.NET中也有RSA算法,请看下面的例子:

    加密过程:

     


            private byte[] rsaCipherText;

            private void mnuAsymmetricEncryption_Click(object sender, RoutedEventArgs e)

            {

                var rsa = 1;

                // Encrypt the data.

                var cspParms = new CspParameters(rsa);

                cspParms.Flags = CspProviderFlags.UseMachineKeyStore;

                cspParms.KeyContainerName = "My Keys";

                var algorithm = new RSACryptoServiceProvider(cspParms);

                var sourceBytes = new UnicodeEncoding().GetBytes(myData);

                rsaCipherText = algorithm.Encrypt(sourceBytes, true);

                MessageBox.Show(String.Format("Data: {0}{1}Encrypted and Encoded: {2}",

                    myData, Environment.NewLine,

                    Convert.ToBase64String(rsaCipherText)));

            }


     

    解密过程:

     


            private void mnuAsymmetricDecryption_Click(object sender, RoutedEventArgs e)

            {

                if(rsaCipherText==null)

                {

                    MessageBox.Show("Encrypt First!");

                    return;

                }

                var rsa = 1;

                // decrypt the data.

                var cspParms = new CspParameters(rsa);

                cspParms.Flags = CspProviderFlags.UseMachineKeyStore;

                cspParms.KeyContainerName = "My Keys";

                var algorithm = new RSACryptoServiceProvider(cspParms);

                var unencrypted = algorithm.Decrypt(rsaCipherText, true);

                MessageBox.Show(new UnicodeEncoding().GetString(unencrypted));

            }


     

    虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。为了解释这个过程,请看下面的例子:

    1 Alice需要在银行的网站做一笔交易,她的浏览器首先生成了一个随机数作为对称密钥。

    2 Alice的浏览器向银行的网站请求公钥。

    3 银行将公钥发送给Alice

    4 Alice的浏览器使用银行的公钥将自己的对称密钥加密。

    5 Alice的浏览器将加密后的对称密钥发送给银行。

    6 银行使用私钥解密得到Alice浏览器的对称密钥。

    7 Alice与银行可以使用对称密钥来对沟通的内容进行加密与解密了。

     


     

    (三)总结

    1 对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。

    2 非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。

    3 解决的办法是将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。


    展开全文
  • 对称加密详解

    2020-12-13 23:27:58
    对称加密1. 对称加密1.1 什么是非对称加密 1. 对称加密 1.1 什么是非对称加密对称加密也叫公钥密码:...发送者用加密密钥消息进行加密,接收者用解密密钥密文进行解密。需理解公钥密码,清楚地分加密

    1. 非对称加密

    1.1 什么是非对称加密

    “非对称加密也叫公钥密码:使用公钥加密,使用私钥解密”

    非对称加密和加密密钥不同
    在对称密码中,由于加密和解密的密钥是相同的,因此必须向接收者配送密钥。用于解密的密钥必须被配送给接收者,这一问题称为密钥配送问题。如果使用非对称加密,则无需向接收者配送用于解密的密钥,这样就解决了密钥配送的问题。

    非对称加密中,密钥分为加密密钥和解密密钥两种。发送者用加密密钥对消息进行加密,接收者用解密密钥对密文进行解密。需理解公钥密码,清楚地分加密密钥和解密密钥是非常重要的。加密密钥是发送者加密时使用的,而解密密钥则是接收者解密时使用的。

    加密密钥和解密密钥的区别
    发送者只需要加密密钥
    接收者只需要解密密钥
    解密密钥不可以被窃听者获取
    加密密钥被窃听者获取也没关系

    也就是说,解密密钥从一开始就是由接收者自己保管的,因此只要将加密密钥发给发送者就可以解决密钥配送问题了,而根本不需要配送解密密钥。

    非对称加密中,加密密钥一般是公开的。真是由于加密密钥可以任意公开,因此该密钥被称为公钥(pulickey)。相对地解密密钥是绝对不能公开的,这个密钥只能由你自己来使用,因此称为私钥(privatekey)****。私钥不可以被别人知道,也不可以将它发送给别人。

    公钥和私钥是"一一对应的",一对公钥和私钥统称为密钥对(keypair)。由公钥进行加密的密文,必须使用与该公钥配对的私钥才能解密。密钥对中的两个密钥之间具有非常密切的的关系(数学上的关系)。因此公钥和私钥不能分别单独生成。

    公钥密码的使用者需要生成一个包括公钥和私钥的密钥对,其中公钥会被发送给别人,而私钥则仅供自己使用。

    1.2 非对称加密通信流程

    非对称加密通讯流程

    假设A要给B发一条信息,A是发送者,B是接收者,窃听者C可以窃听他们之间的通讯内容。

    1. B生成一个包含公钥和私钥的密钥对

      私钥由B自行妥善保管

    2. B将自己的公钥发送给A

      B的公钥被C截获也没关系。
      将公钥发给A,表示B请A用这个公钥对消息进行加密并发送给他。

    3. A用B的公钥对消息进行加密

      加密后的消息只有B的西药才能够解密。
      虽然A拥有B的公钥,但用B的公钥是无法对密文进行解密的。

    4. A将密文发送给B

      密文被C截获也没关系,C可能拥有B的公钥,但是B的公钥是无法进行解密的。

    5. B用自己的私钥对密文进行解密。

      参考下图

    RSA加密流程

    A和B之间传输的信息有两个,一个是B的公钥,一个是B公钥加密的密文,由于B的私钥没有出现在通信内容中,因此C无法对密文进行解密。

    1.3 RSA

    RSA是一种非对称加密算法,它的名字由三位开发者。即RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Leonard)

    1.3.1 RSA加密

    RSA的加密工程可以用下来公式来表达,如下。
    RSA加密公式
    也就是说,RSA的密文是对代表明文的数字的E次方求modN的结果。换句话说,就是将明文自己做E次乘法,然后将其结果除以N求余数,这个余数就是密文。

    RSA的加密是求明文的E次方modN,因此只要知道E和N这两个数,任何人都可以完成加密的运算。所以说E和N是RSA加密的密钥。也就是说E和N的组合就是公钥

    有一个很容易引起误解的地方需要大家注意一一E和N这两个数并不是密钥对(公钥和私钥的密钥对)。E和N两个数才组成了一个公钥,因此我们一般会写成 “公钥是(E,N)” 或者 “公钥是{E, N}" 这样的形式,将E和N用括号括起来。

    1.3.2 RSA解密

    RSA的解密和加密一样简单,可以用下面的公式来表达:
    RSA解密公式

    也就是说,对表示密文的数字的D次方求modN就可以得到明文。换句话说,将密文自己做D次乘法,在对其结果除以N求余数,就可以得到明文。

    这里所使用的数字N和加密时使用的数字N是相同的。数D和数N组合起来就是RSA的解密密钥,因此D和N的组合就是私钥。只有知道D和N两个数的人才能够完成解密的运算。

    大家应该已经注意到,在RSA中,加密和解密的形式是相同的。加密是求 "E次方的mod N”,而解密则是求 "D次方的modN”,这真是太美妙了。

    当然,D也并不是随便什么数都可以的,作为解密密钥的D,和数字E有着相当紧密的联系。否则,用E加密的结果可以用D来解密这样的机制是无法实现的。

    顺便说一句,D是解密〈Decryption)的首字母,N是数字(Number)的首字母

    1.3.3 总结

    总结表格
    RSA加密和解密
    RSA加密和解密

    1.4 ECC椭圆曲线

    椭圆曲线密码学(英语:Elliptic curve cryptography,缩写为 ECC),一种建立公开密钥加密的算法,基于椭圆曲线数学。椭圆曲线在密码学中的使用是在1985年由Neal Koblitz和Victor Miller分别独立提出的。

    ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。

    椭圆曲线密码学的许多形式有稍微的不同,所有的都依赖于被广泛承认的解决椭圆曲线离散对数问题的困难性上。与传统的基于大质数因子分解困难性的加密方法不同,ECC通过椭圆曲线方程式的性质产生密钥。

    ECC 164位的密钥产生的一个安全级相当于RSA 1024位密钥提供的保密强度,而且计算量较小,处理速度更快,存储空间和传输带宽占用较少。目前我国居民二代身份证正在使用 256 位的椭圆曲线密码,虚拟货币比特币也选择ECC作为加密算法。
    具体算法详解:
    链接:算法详解

    不管是RSA还是ECC或者其它,公钥加密算法都是依赖于某个正向计算很简单(多项式时间复杂度),而逆向计算很难(指数级时间复杂度)的数学问题。

    椭圆曲线依赖的数学难题是:

    k为正整数,P是椭圆曲线上的点(称为基点), k*P=Q , 已知Q和P,很难计算出k

    展开全文
  • 比如a向b发送消息:holle,按英文字母分别向后移动12345进行加密,那么得到的加密后的是消息是:isooj,将isooj发送给b,b再按按英文字母向前移123456位,则解密出holle这个正确的消息。这就是对称加密。 但是对称...
  • 文章目录1.1 密码学基本概念1.1.1 古典密码学1.1.2 近代密码学1.1.3 现代密码学1.1.4 如何设置密码才安全1.2 ASCII编码1.3 恺撒加密...英文对应的字节1.6 常见加密方式1.6.1 对称加密的概念1.6.2 DES 加密解密1)DES 加
  • 对称加密算法和对称加密算法

    千次阅读 2019-03-17 15:59:04
    有一种加密算法叫做对称加密,对称加密是以前比较常见的一种加密方式。所谓对称加密的意思是说假如有一个人A,他想把一个信号m传递给B,他不能直接将这个信息传递给B,否则会有人可能会窃听。于是通过一些算法,...
  • 什么是编码? Base64 解码原理 Base64 问题解答 什么是加密加密的诞生 对称加密 对称加密 Hash 算法
  •  单向加密又称为不可逆加密算法,在加密过程中不使用密钥,明文由系统加密处理成密文,密文无法解密。一般适合于验证,在验证过程中,重新输入明文,并经过同样的加密算法处理,得到相同的密文并被系统重新认证。...
  • 对称加密对称加密介绍和区别   什么是对称加密技术?  对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方法在密码学中叫做对称加密...
  • 对称&对称加密

    2018-08-25 17:25:22
    对称加密英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。实务上,这组密钥...
  • 对称加密算法

    2019-01-31 17:16:13
    搞清楚一个问题:对称加密算法是私钥加密则公钥解密,公钥加密则私钥解密?椭圆曲线算法也是这样吗? 参考: RSA加密算法 椭圆曲线加密算法 对称加密概述 ...
  • 对称加密 发送方和接收方 用同一个秘钥数据加密解密 ...对称加密 发送方用接收方的公钥加密,接收方用自己的私钥解密 例: A生成"APrikey","APubkey" B生成"BPrikey","BPubkey" A给B发消息:
  • #对称加密 ,主要两个问题,确认数据来源,确认数据不被解密  (AB 之间进行通信)  1、首先A B 各自生成有公钥私钥,公钥经过CA认证(数字证书),为唯一的。只有自己的私钥才能解密公钥加密的数据  2、A拿到B...
  • 对称加密

    千次阅读 2011-09-20 11:43:07
    英语:Public-key cryptography,也称为对称金钥加密),该思想最早由雷夫·莫寇(Ralph C. Merkle)在1974年提出[1],之后在1976年。狄菲(Whitfield Diffie)與赫爾曼(Martin Hellman)兩位學者
  • 加密方式从密钥是否相同的角度分为对称加密对称加密。 对称加密:“加密”和“解密”使用【相同的】密钥。 对称加密:“加密”和“解密”使用【不相同的】密钥。 对称加密服务端生成一对密钥(公钥和私钥)...
  • RSA AES-对称加密对称加密

    千次阅读 2018-11-11 02:50:35
    2.客户端:身份证信息(重要信息)进行AES加密 3.客户端:通过使用RSAAES密钥进行公钥加密 4.服务端:对加密后的AES密钥进行RSA私钥解密,拿到密钥原文; 5.服务端:对加密后的重要信息进行AES解密,拿到原始...
  • 四、对称加密

    2019-04-12 19:37:19
    对称加密也叫公钥密码: 使用公钥加密, 使用私钥解密 在对称密码中,由于加密和解密的密钥是相同的,因此必须向接收者配送密钥。用于解密的密钥必须被配送给接收者,这一问题称为密钥配送...发送者用加密密钥消息...
  • 按照密码体制分类,密码加密主要分为对称加密对称加密两大类。接下来,主要讲解这两者的原理与区别。 一、对称加密 1、原理 通信双方使用同一个密钥,使用加密算法配合上密钥来加密,解密时使用加密...
  • 对称加密英语:asymmetric cryptography),是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;一个用作加密的时候,另一个则用作解密。使用其中一个密钥把明文加密后所得的密文,只能用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,884
精华内容 18,353
关键字:

英文非对加密