常见加密相关算法简介

常见加密相关算法简介

消息摘要算法
对称加密算法
非对称加密算法
国密算法

消息摘要算法:

相同的明文数据经过相同的消息摘要算法会得到相同的密文结果值。
数据经过消息摘要算法处理,得到的摘要结果值,是无法还原为处理前的数据的。
数据摘要算法也被称为哈希(Hash)算法或散列算法。
消息摘要算法一般用于签名验签。
消息摘要算法主要分三类:MD(Message Digest,消息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)和MAC(Message
Authentication Code,消息认证码算法)。

在这里插入图片描述
MD家族算法

MD(Message Digest,消息摘要算法)家族,包括MD2,MD4,MD5。

MD2,MD4,MD5 计算的结果都是是一个128位(即16字节)的散列值,用于确保信息传输完整一致。
MD2的算法较慢但相对安全,MD4速度很快,但安全性下降,MD5则比MD4更安全、速度更快。
MD5被广泛应用于数据完整性校验、数据(消息)摘要、数据加密等。
MD5,可以被破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞攻击,因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

ShA家族算法
SHA(Secure Hash Algorithm,安全散列算法),包括SHA-0、SHA-1、SHA-2(SHA-256,SHA-512,SHA-224,SHA-384等)、SHA-3。它是在MD算法基础上实现的,与MD算法区别在于「摘要长度」,SHA 算法的摘要「长度更长,安全性更高」。

SHA-0发布之后很快就被NSA撤回,因为含有会降低密码安全性的错误,它是SHA-1的前身。
SHA-1在许多安全协议中广为使用,包括TLS、GnuPG、SSH、S/MIME和IPsec,是MD5的后继者。
SHA-2包括SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。它的算法跟SHA-1基本上相似,目前还没有出现明显弱点。
SHA-3是2015年正式发布,由于对「MD5出现成功的破解」,以及对SHA-0和SHA-1出现理论上破解的方法,SHA-3应运而生。它与之前算法不同的是,它是可替换的加密散列算法。
SHA-1、SHA-2(SHA-256,SHA-512,SHA-224,SHA-384)等算法是比较常用的,我们来看看跟MD5的对比吧

在这里插入图片描述
MAC算法家族
MAC算法 MAC(Message Authentication Code,消息认证码算法),是带密钥的Hash函数。输入密钥和消息,输出一个消息摘要。它集合了MD和SHA两大系列消息摘要算法。

MD 系列算法: HmacMD2、HmacMD4 和 HmacMD5 ;
SHA 系列算法:HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384 和 HmacSHA512 。

对称加密算法
加密和解密使用「相同密钥」的加密算法就是对称加密算法。常见的对称加密算法有AES、3DES、DES、RC5、RC6等。
在这里插入图片描述
DES

数据加密标准(英语:Data Encryption Standard,缩写为
DES)是一种对称密钥加密块密码算法。DES算法的入口参数有三个:Key、Data、Mode。

Key: 7个字节共56位,是DES算法的工作密钥; Data: 8个字节64位,是要被加密或被解密的数据; Mode: 加密或解密。

3DES

三重数据加密算法(英语:Triple Data Encryption Algorithm,又称3DES(Triple
DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次数据加密标准(DES)算法。

AES

AES,高级加密标准(英语:Advanced Encryption
Standard),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

采用对称分组密码体制,密钥长度为 128 位、 192 位、256 位,分组长度128位 相对于DES ,AES具有更好的 安全性、效率 和灵活性。

非对称加密算法

非对称加密算法需要两个密钥:公钥和私钥。公钥与私钥是成对存在的,如果用公钥对数据进行加密,只有用对应的私钥才能解密。主要的非对称加密算法有:RSA、Elgamal、DSA、D-H、ECC。
在这里插入图片描述

RSA算法

RSA加密算法是一种非对称加密算法,广泛应用于加密和数字签名
RSA算法原理:两个大素数的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
RSA是被研究得最广泛的公钥算法,从提出到现在,经历了各种攻击的考验,普遍认为是目前最优秀的公钥方案之一。

DSA

DSA(Digital Signature Algorithm,数字签名算法),也是一种非对称加密算法。
DSA和RSA区别在,DSA仅用于数字签名,不能用于数据加密解密。其安全性和RSA相当,但其性能要比RSA好。

ECC 算法

ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学),基于椭圆曲线加密。
Ecc主要优势是,在某些情况下,它比其他的方法使用更小的密钥,比如RSA加密算法,提供相当的或更高等级的安全级别。
它的一个缺点是,加密和解密操作的实现比其他机制时间长 (相比RSA算法,该算法对CPU 消耗严重)。

国密算法
国密即国家密码局认定的国产密码算法。为了保障商用密码的安全性,国家商用密码管理办公室制定了一系列密码标准,即SM1,SM2,SM3,SM4等国密算法。
在这里插入图片描述
SM1

SM1,为对称加密算法,加密强度为128位,基于硬件实现。 SM1的加密强度和性能,与AES相当。

SM2

SM2主要包括三部分:签名算法、密钥交换算法、加密算法 SM2用于替换RSA加密算法,基于ECC,效率较低。

SM3

SM3,即国产消息摘要算法。 适用于商用密码应用中的数字签名和验证,消息认证码的生成与验证以及随机数的生成。

SM4

SM4是一个分组算法,用于无线局域网产品。 该算法的分组长度为128比特,密钥长度为128比特。
加密算法与密钥扩展算法都采用32轮非线性迭代结构。 解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
它的功能类似国际算法的DES。

加签验签相关Java的API
在这里插入图片描述

加签验签代码实现
前几个小节讨论完概念,是时候上代码实战了,我这边用的是SHA-256作为摘要算法,RSA作为签名验签算法,如下:

package pattern;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * 加签验签demo
 *  @Author 捡田螺的小男孩
 */
public class SignatureTest {
    //公钥字符串
    private static final String PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaJzVjC5K6kbS2YE2fiDs6H8pB\n" +
            "JFDGEYqqJJC9I3E0Ebr5FsofdImV5eWdBSeADwcR9ppNbpORdZmcX6SipogKx9PX\n" +
            "5aAO4GPesroVeOs91xrLEGt/arteW8iSD+ZaGDUVV3+wcEdci/eCvFlc5PUuZJou\n" +
            "M2XZaDK4Fg2IRTfDXQIDAQAB";
    //私钥字符串
    private static final String PRIVATE_KEY_STR = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANonNWMLkrqRtLZg\n" +
            "TZ+IOzofykEkUMYRiqokkL0jcTQRuvkWyh90iZXl5Z0FJ4APBxH2mk1uk5F1mZxf\n" +
            "pKKmiArH09floA7gY96yuhV46z3XGssQa39qu15byJIP5loYNRVXf7BwR1yL94K8\n" +
            "WVzk9S5kmi4zZdloMrgWDYhFN8NdAgMBAAECgYA9bz1Bn0i68b2KfqRdgOfs/nbe\n" +
            "0XNN1DLQp2t7WDfRCg01iI1zPkZgyFVZWtI85f5/uIrLs5ArLosL1oNuqqc0nNne\n" +
            "CvJK+ZxvA98Hx3ZqYTzDnleR054YhofL5awbhSciYVic204DOG1rhSsYWMqtX7J7\n" +
            "3geoWL7TYdMfYXcCAQJBAPMMKsz6ZJh98EeQ1tDG5gpAGWFQkYNrxZDelP/LjeO0\n" +
            "TP3XkQnIpcaZoCs7V/rRGRGMWwQ2BUdc/01in89ZZ5ECQQDlx2oBc1CtOAm2UAhN\n" +
            "1xWrPkZWENQ53wTrwXO4qbTGDfBKon0AehLlGCSqxQ71aufLkNO7ZlX0IHTAlnk1\n" +
            "TvENAkAGSEQ69CXxgx/Y2beTwfBkR2/gghKg0QJUUkyLqBlMz3ZGAXJwTE1sqr/n\n" +
            "HiuSAiGhwH0ByNuuEotO1sPGukrhAkAMK26a2w+nzPL+u+hkrwKPykGRZ1zGH+Cz\n" +
            "19AYNKzFXJGgclCqiMydY5T1knBDYUEbj/UW1Mmyn1FvrciHoUG1AkAEMEIuDauz\n" +
            "JabEAU08YmZw6OoDGsukRWaPfjOEiVhH88p00veM1R37nwhoDMGyEGXVeVzNPvk7\n" +
            "cELg28MSRzCK";


    public static void main(String[] args) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException, InvalidKeySpecException {
        //原始报文
        String plain = "欢迎大家关注我的公众号,捡田螺的小男孩";
        //加签
        byte[] signatureByte = sign(plain);
        System.out.println("原始报文是:" + plain);
        System.out.println("加签结果:");
        System.out.println(new BASE64Encoder().encode(signatureByte));
        //验签
        boolean verifyResult = verify(plain, signatureByte);
        System.out.println("验签结果:" + verifyResult);
    }

    /**
     * 加签方法
     * @param plain
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws UnsupportedEncodingException
     * @throws SignatureException
     */
    private static byte[] sign(String plain) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, SignatureException {
        //根据对应算法,获取签名对象实例
        Signature signature = Signature.getInstance("SHA256WithRSA");
        //获取私钥,加签用的是私钥,私钥一般是在配置文件里面读的,这里为了演示方便,根据私钥字符串生成私钥对象
        PrivateKey privateKey = getPriveteKey(PRIVATE_KEY_STR);
        //初始化签名对象
        signature.initSign(privateKey);
        //把原始报文更新到对象
        signature.update(plain.getBytes("UTF-8"));
        //加签
        return signature.sign();
    }

    /**
     * 验签方法
     * @param plain
     * @param signatureByte
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IOException
     * @throws SignatureException
     * @throws InvalidKeySpecException
     */
    private static boolean verify(String plain, byte[] signatureByte) throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, InvalidKeySpecException {
        //获取公钥
        PublicKey publicKey = getPublicKey(PUBLIC_KEY_STR);
        //根据对应算法,获取签名对象实例
        Signature signature = Signature.getInstance("SHA256WithRSA");
        //初始化签名对象
        signature.initVerify(publicKey);
        //把原始报文更新到签名对象
        signature.update(plain.getBytes("UTF-8"));
        //进行验签
        return signature.verify(signatureByte);
    }

    private static PublicKey getPublicKey(String publicKeyStr) throws InvalidKeySpecException, IOException {
        PublicKey publicKey = null;
        try {
            java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
                    new BASE64Decoder().decodeBuffer(publicKeyStr));
            // RSA对称加密算法
            java.security.KeyFactory keyFactory;
            keyFactory = java.security.KeyFactory.getInstance("RSA");
            // 生成公钥对象
            publicKey = keyFactory.generatePublic(bobPubKeySpec);
           } catch (NoSuchAlgorithmException e) {
             e.printStackTrace();
            }
        return publicKey;
      }

    private static PrivateKey getPriveteKey(String privateKeyStr) {
        PrivateKey privateKey = null;
        PKCS8EncodedKeySpec priPKCS8;
        try {
            priPKCS8 = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(privateKeyStr));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            privateKey = keyf.generatePrivate(priPKCS8);
        } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return privateKey;
    }
}

加签结果:
Oz15/aybGe42eGHbc+iMoSYHSCc8tfRskTVjjGSTPD4HjadL0CC5JUWNUW0WxHjUb4MvxWo2oeWE
Qw0+m61d+JgBMto/TWcVDcgwL/AbObsbWdQ6E/fVRqG13clkE8MyKsjt9Z7tcbwpycYTv0rUR4co
rndAVfBdtv5KeV+OXqM= 验签结果:true

Reference
[1] 维基百科: https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5

[2] 百度百科: https://baike.baidu.com/

[3] 常用消息摘要算法简介: https://cloud.tencent.com/developer/article/1584742

[4] 浅谈常见的七种加密算法及实现:
https://juejin.im/post/5b48b0d7e51d4519962ea383#heading-12

[5] 【易错概念】国密算法SM1(SCB2)、SM2、SM3、SM4、SM7、SM9、ZUC:
https://www.jianshu.com/p/8c3657a1769f

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值