0


常见的对称式加密与非对称式加密算法

1.概述

    **对称式加密**:对称加密算法就是传统的用一个密码进行加密和解密,通信发送方使用这种算法加密数据,接收方也用同样的算法解密数据. 因此对称式加密本身不是安全的。从程序的角度看,所谓加密,就是这样一个函数:

    它接收密码和明文,然后输出密文: secret = encrypt(key, message); 而解密则相反,它接收密码和密文,然后输出明文: plain = decrypt(key, secret);

    常见的对称式加密算法:

算法秘钥长度工作模式填充模式AES56/64ECB/CBC/PCBC/CTR/...NoPadding/PKCS5Padding/...DES128/192/256ECB/CBC/PCBC/CTR/..NoPadding/PKCS5Padding/PKCS7Padding/...IDEA128ECBPKCS5Padding/PKCS7Padding/...
密钥长度直接决定加密强度,而工作模式和填充模式可以看成是对称加密算法的参数和格式选择。Java标准库提供的算法实现并不包括所有的工作模式和所有填充模式,但是通常我们只需要挑选常用的使用就可以了。

   ** 非对称式加密:**加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密,例如:小明要加密一个文件发送给小红,他应该首先向小红索取她的公钥,然后,他用小红的公钥加密,把加密文件发送给小红,此文件只能由小红的私钥解开,因为小红的私钥在她自己手里,所以,除了小红,没有任何人能解开此文件。

    非对称加密的优点:对称加密需要协商密钥,而非对称加密可以安全地公开各自的公钥,在N个人之间通信的时候:使用非对称加密只需要N个密钥对,每个人只管理自己的密钥对。而使用对称加密需要则需要N*(N-1)/2个密钥,因此每个人需要管理N-1个密钥,密钥管理难度大,而且非常容易泄漏。

    非对称加密的缺点:运算速度非常慢,比对称加密要慢很多

    非对称加密的典型算法就是RSA算法,它是由Ron Rivest,Adi Shamir,Leonard Adleman这三个人一起发明的,所以用他们三个人的姓氏首字母缩写表示。

2.使用AES加密

1.根据算法名称/工作模式/填充模式获取Cipher实例;

2 根据算法名称初始化一个SecretKey实例,密钥必须是指定长度;

3 使用SerectKey初始化Cipher实例,并设置加密或解密模式;

4 传入明文或密文,获得密文或明文。

public class AES_Test {
    public static void main(String[] args) throws Exception{
        String message = "HelloWorld";
        System.out.println("原始内容:" +message);
        
        //128位秘钥=16 bytes key:
        byte[] key = "1234567996xxyabc".getBytes();
        
        //加密:
        byte[] data = message.getBytes();
        byte[] encrypted = encrypt(key,data);
        System.out.println("加密结果: "+Base64.getEncoder().encodeToString(encrypted));
        
        //解密:
        byte[] decrypted = decrypt(key,encrypted);
        System.out.println("解密结果: "+new String(decrypted));
        
    }
    //加密:
    public static byte[] encrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        //创建密码对象,需要传入算法/工作模式/填充模式
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        
        //根据key的字节内容,"恢复"密码对象
        SecretKey keySpec = new SecretKeySpec(key, "AES");
        //初始化秘钥,设置加密模式ENCRYPT_MODE
        cipher.init(cipher.ENCRYPT_MODE, keySpec);
        //根据原始内容(字节),进行加密
        return cipher.doFinal(input);        
    }
    //解密:
    public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        //创建密码对象,需要传入算法/工作模式/填充模式
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        
        //根据key的字节内容,"恢复"密码对象
        SecretKey keySpec = new SecretKeySpec(key, "AES");
        //初始化秘钥,设置解密模式DECRYPT_MODE
        cipher.init(cipher.DECRYPT_MODE, keySpec);
        //根据原始内容(字节),进行解密
        return cipher.doFinal(input);        
    }
}

输出结果:

原始内容:HelloWorld
加密结果: z0cr9rJRvwNu9V7D6EOlzw==
解密结果: HelloWorld

3.RSA加密算法

import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;

// RSA
public class Main {
    public static void main(String[] args) throws Exception {
        // 明文:
        byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");

        // 创建公钥/私钥对:
        Human alice = new Human("Alice");

        // 用Alice的公钥加密:
        // 获取Alice的公钥,并输出
        byte[] pk = alice.getPublicKey();
        System.out.println(String.format("public key(公钥): %x", new BigInteger(1, pk)));

        // 使用公钥加密
        byte[] encrypted = alice.encrypt(plain);
        System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));

        // 用Alice的私钥解密:
        // 获取Alice的私钥,并输出
        byte[] sk = alice.getPrivateKey();
        System.out.println(String.format("private key(私钥): %x", new BigInteger(1, sk)));

        // 使用私钥解密
        byte[] decrypted = alice.decrypt(encrypted);
        System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
    }
}

// 用户类
class Human {
    // 姓名
    String name;

    // 私钥:
    PrivateKey sk;

    // 公钥:
    PublicKey pk;

    // 构造方法
    public Human(String name) throws GeneralSecurityException {
        // 初始化姓名
        this.name = name;

        // 生成公钥/私钥对:
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
        kpGen.initialize(1024);
        KeyPair kp = kpGen.generateKeyPair();

        this.sk = kp.getPrivate();
        this.pk = kp.getPublic();
    }

    // 把私钥导出为字节
    public byte[] getPrivateKey() {
        return this.sk.getEncoded();
    }

    // 把公钥导出为字节
    public byte[] getPublicKey() {
        return this.pk.getEncoded();
    }

    // 用公钥加密:
    public byte[] encrypt(byte[] message) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, this.pk); // 使用公钥进行初始化
        return cipher.doFinal(message);
    }

    // 用私钥解密:
    public byte[] decrypt(byte[] input) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, this.sk); // 使用私钥进行初始化
        return cipher.doFinal(input);
    }
}
    RSA算法的密钥有256/512/1024/2048/4096等不同的长度。长度越长,密码强度越大,当然计算速度也越慢。

4.总结:

    1.加密和解密过程不同 :对称加密过程和解密过程使用的同一个密钥,加密过程相当于用原文+密钥可以传输出密文,同时解密过程用密文-密钥可以推导出原文。但非对称加密采用了两个密钥,一般使用公钥进行加密,使用私钥进行解密。

     2.加密解密速度不同 : 对称加密解密的速度比较快,适合数据比较长时的使用。非对称加密和解密花费的时间长、速度相对较慢,只适合对少量数据的使用。  

    3.传输的安全性不同 : 对称加密的过程中无法确保密钥被安全传递,密文在传输过程中是可能被第三方截获的,如果密码本也被第三方截获,则传输的密码信息将被第三方破获,安全性相对较低。  非对称加密算法中私钥是基于不同的算法生成不同的随机数,私钥通过一定的加密算法推导出公钥,但私钥到公钥的推导过程是单向的,也就是说公钥无法反推导出私钥。所以安全性较高。
标签: java 安全 eclipse

本文转载自: https://blog.csdn.net/qq_55897122/article/details/125964801
版权归原作者 以月光下洒 所有, 如有侵权,请联系我们删除。

“常见的对称式加密与非对称式加密算法”的评论:

还没有评论