加密和验签

这篇具有很好参考价值的文章主要介绍了加密和验签。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、加密与验签介绍

  大多数公共网络是不安全的,一切基于HTTP协议的请求/响应(Request or Response)都是可以被截获的、篡改、重放(重发)的。因此我们需要考虑以下几点内容:

  1. 防伪装攻击(案例:在公共网络环境中,第三方 有意或恶意 的调用我们的接口)
  2. 防篡改攻击(案例:在公共网络环境中,请求头/查询字符串/内容 在传输过程被修改)
  3. 防重放攻击(案例:在公共网络环境中,请求被截获,稍后被重放或多次重放)
  4. 防数据信息泄漏(案例:截获用户登录请求,截获到账号、密码等)

​ 区分签名与加密的概念

   ​   签名:目的是为了验证身份,检查篡改,防止重放,防止中间人假装自己对外发送假信息,不需要对数据进行加密处理,因此用私钥进行签名,用公钥进行解密验证。也有一些不可逆算法,两边生成签名之后比对结果

​      加密:目的是将明文变成密文进行传输,防止消息在传输中被别人破解,因此使用公钥加密,使用私钥解密

总结:公钥加密、私钥解密、私钥签名、公钥验签

加密算法我们整体可以分为:可逆加密和不可逆加密,可逆加密又可以分为:对称加密和非对称加密,不可逆算法不用于数据加密,常用于签名算法;可逆算法常用于消息加密算法 

比较推荐的几个加密算法有:

  • 不可逆加密:SHA256SHA384SHA512以及HMAC-SHA256HMAC-SHA384HMAC-SHA512
  • 对称加密算法:AES3DES
  • 非对称加密算法:RSA

可逆与不可逆算法,对称加密与非对称加密算法总结_柠檬不萌的技术博客_51CTO博客

面试官:说一下你常用的加密算法-阿里云开发者社区

二、签名算法也称摘要算法

  • 应用场景:检查报文正确性、验证身份,防止重放(可通过加时间戳的方式)
  • 方案:从报文文本中生成报文摘要
  • 常用:SHA或者MD5作为签名算法
  • 缺点:签名算法不是加密算法,不能用来加密

三、消息加密算法

一. 数字加密算法
数字加密算法中,通常可划分为对称加密和非对称加密。
1. 对称加密
     概念:加密和解密使用同一个密钥,所以叫做对称加密。
     常见的对称加密算法:DES,AES。

加密和验签

2. 非对称加密
      概念:加密和解密使用两个的密钥,一把作为公开的公钥(Public Key),另一把作为私钥(Private Key)。因为加密和解密使用的不是同一把密钥,所以这种算法称为非对称加密算法。
公钥和私钥成对存在,通常【公钥加密,私钥解密】;
公钥是基于私钥而存在的。通过私钥经过一系列算法是可以推导出公钥,但无法通过公钥反向推倒出私钥。
      常见的非对称加密算法:RSA,ECC。

加密和验签
3. 对称加密和非对称加密的区别
对称加密:加解密效率高。但在非安全信道中通讯时,密钥交换的安全性不能保障。
非对称加密:加解密效率低,但可以保证密钥安全性。
通常在实际的网络环境中,会将两者混合使用。两者混合使用的示例如下:

 加密和验签

四、接口验签实操

1. 实操说明

  接口加密与验签的方法有非常多,比如RSA(后期进行讲解),基于token等方式,而对于普通项目,我认为最重要的是防伪装攻击、防篡改攻击、防重放攻击。因为接下来的实操,主要围绕以下几点进行。

2. 验签实操--HMAC-摘要加密算法-不可逆-需密钥

  入参sign字段-接口调用方按相同算法进行计算得出摘要

  提供方通过如下方式计算得出摘要,比如入参摘要和计算得出的摘要比对一致验签通过。

  验签通过的前提下,校验入参传入ts,时间戳若时间差超过5s则不通过。

    /**
     * 摘要验证
     * @param vo 带摘要的请求vo
     * @return
     */
    protected void verifyDigest(BaseDigestReqVO vo) {
        Assert.notBlank(vo.getSign(), "[接口回调] 入参有误,sign不能为空");

        Assert.notNull(vo.getTs(), "[接口回调] 入参有误,ts不能为空");

        // 获取HMAC对象,该对象本身不保证线程安全,每次都需要进行实例化
        //利用hutool工具类cn.hutool.crypto.SecureUtil
        //getKey()方法为获取密钥String字符串的方法,也可以写死,调用方和提供方使用的密钥相同:cn.hutool.crypto.KeyUtil生成密钥的工具类
        HMac hMac = SecureUtil.hmacSha256(getKey());
        // sign本身不参与签名
        String beforeStr = Arrays.stream(ReflectUtil.getFields(vo.getClass(), field -> ObjectUtil.notEqual(field.getName(), "sign")))
                // 按照字段名字典排序
                .sorted(Comparator.comparing(Field::getName))
                // 取出所有value
                .map(field -> ReflectUtil.getFieldValue(vo, field).toString())
                // 用&进行拼接
                .collect(Collectors.joining("&"));
        byte[] digest = hMac.digest(beforeStr);

        Assert.isTrue(hMac.verify(digest, HexUtil.decodeHex(vo.getSign())), "[接口回调] 入参有误,签名错误");
       //防止重放攻击-判断ts在5秒内误差
        Assert.isTrue(verifyTs(vo.getTs()), "[接口回调] 入参有误,ts不在有效的范围内");
    }

3.消息加密算法--可逆-生成私钥和公钥并用私钥加密原文实操举例

//生成密钥对的方式也可以使用hutool中的工具类cn.hutool.crypto.KeyUtil生成密钥的工具类,代码会更简洁

public class RsaDemo {
    public static void main(String[] args) throws Exception {
        String input = "读你千遍";
        // 算法
        String algorithm = "RSA";

        // 生成密钥对
        KeyPair keyPair = getPrivatePublicKey(algorithm);

        // 使用私钥对原文加密
        byte[] bytes = privateKeyEncrypt(input, algorithm, keyPair.getPrivate());

        // 使用私钥对原文解密,使用私钥加密必须用公钥解密
        privateKeyDecrypt(bytes, algorithm, keyPair.getPublic());
    }

    /**
     * 使用私钥对原文加密
     *
     * @param input
     * @param algorithm
     * @param privateKey
     */
    private static byte[] privateKeyEncrypt(String input, String algorithm, PrivateKey privateKey) throws Exception {
        // 创建加密对象
        Cipher cipher = Cipher.getInstance(algorithm);
        // 加密初始化:加密模式,想使用私钥进行加密
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        // 使用私钥对原文加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        System.out.println("加密:\n" + Base64.encode(bytes));
        return bytes;
    }

    /**
     * 使用私钥对原文解密
     *
     * @param input
     * @param algorithm
     * @param publicKey 使用私钥加密必须用公钥解密
     */
    private static void privateKeyDecrypt(byte[] input, String algorithm, PublicKey publicKey) throws Exception {
        // 创建加密对象
        Cipher cipher = Cipher.getInstance(algorithm);
        // 解密初始化:解密模式,想使用公钥进行解密
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        // 使用私钥对原文加密
        byte[] bytes = cipher.doFinal(input);
        System.out.println("解密:\n" + new String(bytes));
    }

    /**
     * 生成密钥对
     *
     * @param algorithm
     * @return
     */
    private static KeyPair getPrivatePublicKey(String algorithm) throws Exception {
        // 创建密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        // 生成密钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        byte[] privateKeyEncoded = privateKey.getEncoded();
        byte[] publicKeyEncoded = publicKey.getEncoded();

        System.out.println("私钥:\n" + Base64.encode(privateKeyEncoded));
        System.out.println("公钥:\n" + Base64.encode(publicKeyEncoded));
        return keyPair;
    }
}

输出结果

私钥:
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCOhxmGwp2dHQYCZHkxzO4EVb0lff6l/7K4p+1zZHLKBVdM7Hejm+EdFPf7CJfi44d5JHYcZSegssI8bm80sg1s38F8yfNmyZde/11aH351HFErNqYQ3KcwF8vOEg+7Ywm4PVfF0uAoLTR4KBgwXwuHUyEw80W0ADcpY8TVQe31NjJBXNK9QltoQRjrVDV8M9dJkP0QnJ2uEVU6rOyJIgMzFl+CdFmlym5AyAZFWxqDtkSbVjMsk/N5YrMTzOEhUPksEtFu4Tvv9rLe6R92287LY2b64aORc3OP40T5g+JJ4arsmG7lNjvUL/bg43Dq1uktbjMJSKWlOziIGB9Y9OpdAgMBAAECggEAX2jCxro6xjTqk+lsU9EKOC6o+pMYR0ke+4u2YXuJeAERSrY09HnhvRUPV6WN/10ukAK/agyw9VsUuV135f+XCx3SKVYLMPCb+wTZGf5hKcY188aWbk03QfN8A8uFanxGwmWV/yBF278/E3xLjP3i+sjEPD9tlqxaQMO/vL5wq6eD06RENDhmV3Di3sPPk0LMJPg4gtrWvM+TNGzHvsliADC2yHYuTSbAnTvetQJvVUizMJi2YALyFSOBnPeEiEsecTXBFwpHcU+GK60IIGanW6U3xSC7BjZu/vEpWiewVfFWSIj6ELZeCgXYpINrU6ABIheNr34oVrynONjwEcFmAQKBgQDhIY6EvOpV9iGbY00DnNgT+0TRQx2QGDIcM/KMcuwptKgGsWMBPvoRJnwQvgLLmgCPX7SQrAUk+/QvhTgXQgNoeJMb2slB17rKAdM3/qKTCBN+oZ8WbC9HrcWB5AuNWQLSaRmqIN47CdI2rN24GfpYOw5urIwINdDr7CIvdTHdgQKBgQCiEgo17wtlEdJnhFAZVC9CuIPjtQ/Ys8an9gKQDiymCPHqVgrkkzPhTSGE9fg0chkLjvi4hrNVwGHjRTyXUQFyB2o+zuZJYBQLw2i7P001hHZz/y76mTL8Oue1QhqbvJ4MpBtrV8yMBKrRxWt/BF4lY+DN2aRezkAawWMmnWWy3QKBgDqLsndcdYhDSLwTF80PtbWEi4Hr9T0qvaVN8Q6LOFUkMOoEqV2Clh9tpafo8esmsmyWk+tngLL8fqT4/Pw3Y5GAgaklvV7NDjtIPDh8lKSt3fv5Zdi765O1Yf6EYmiwtCYpxM3UXFZ4GF21mLcuskbNnNQ1NPlRnXIs5zr2PDCBAoGBAIPj9GVBvF8qqrRNK7YBGVjNuZ8UGOo8Gt1SyXEb59/ShbQzAzhSRrUBxNZkKPHdLF6IogXgsI6HOeHu1Uk6xddbC25Dh4qM4qNUCaXf9OAphRAOyddr1t8GvMt4GRlF3MTiw+GOGMqVfcGqTDmYf1kkN6ytgiMY63gaiqrBCiMNAoGBAJzoOmipXLXrpH6WS/8NN2cHOIpfK/Nco84XUpTQaihkW3nGsypVRCLmtJgsa55Efa0/T9wVqgPfYf++IHVBidvH4+KrPBetqWF0Q8km0K00DV9OXUnhRDabM4+jlaxnf4VaxWTJDNLf2cAsHwzlVMZkwT/4EsxwRggjUZTMsn6N
公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjocZhsKdnR0GAmR5MczuBFW9JX3+pf+yuKftc2RyygVXTOx3o5vhHRT3+wiX4uOHeSR2HGUnoLLCPG5vNLINbN/BfMnzZsmXXv9dWh9+dRxRKzamENynMBfLzhIPu2MJuD1XxdLgKC00eCgYMF8Lh1MhMPNFtAA3KWPE1UHt9TYyQVzSvUJbaEEY61Q1fDPXSZD9EJydrhFVOqzsiSIDMxZfgnRZpcpuQMgGRVsag7ZEm1YzLJPzeWKzE8zhIVD5LBLRbuE77/ay3ukfdtvOy2Nm+uGjkXNzj+NE+YPiSeGq7Jhu5TY71C/24ONw6tbpLW4zCUilpTs4iBgfWPTqXQIDAQAB
加密:
a1UuipQu38r5lTtBVA3JnGPjLqHrAbMwXacPjOl3pzKl9Vkv/1D3tjAJw4dKlt/VHD1kPJmlvjQG4op+JODR/MrwyhZCB6bpVG0HMkqCrk8RBiGQYrxAN0H6fuEx2KtoV9HjroU+hIXM1C7SD6Kx5ss26Wb82UXsSmuIx+aGr8794fsamK9SxGTcyKYiPRrKK+PnJHDif1+2FHKrPVmWFJPFR8gUSGXYsyGTyBZarFK1bXgKGBJBF6nZ6ju3uc4g7KWbxQLsj3U2Lzz2m3U+SHEqobtWi0ssoEWdAQJUWfKdLBcvghKEyGbzQyHUfyY7sW4HIbcCYFDEA4buYZqWgw==
解密:
读你千遍

4.数字签名-是非对称密钥加密技术与摘要算法的结合应用。

加密和验签

 

张三有俩好哥们A、B。由于工作原因,张三和 AB 写邮件的时候为了安全都需要加密。于是张三想到了数字签名:

  1. 加密采用非对称加密,张三有三把钥匙,两把公钥,送给朋友。一把私钥留给自己。
  2. A或者B写邮件给张三:A 先用公钥对邮件加密,然后张三收到邮件之后使用私钥解密。
  3. 张三写邮件给 A 或者 B:
    • 张三写完邮件,先用 hash 函数生成邮件的摘要,附着在文章上面,这就完成了数字签名,然后张三再使用私钥加密。就可以把邮件发出去了。
    • A 或者是 B 收到邮件之后,先把数字签名取下来,然后使用自己的公钥解密即可。这时候取下来的数字签名中的摘要若和张三的一致,那就认为是张三发来的,再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

加密和验签

加密和验签文章来源地址https://www.toymoban.com/news/detail-466166.html

到了这里,关于加密和验签的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • R语言【base】——data.frame():创建数据框,紧耦合的变量集合,它们共享矩阵和列表的许多属性,被大多数R建模软件用作基本数据结构。

    Package  base  version 4.2.0 创建数据框(data frame),紧耦合的变量集合,它们共享矩阵和列表的许多属性,被大多数R建模软件用作基本数据结构。 数据框:一种在统计分析和数据处理中常用的数据结构,由行和列组成,类似于电子表格。 参数【...】:这些参数的形式是 value 或

    2024年02月21日
    浏览(49)
  • 加密和验签

      大多数公共网络是不安全的,一切基于HTTP协议的请求/响应(Request or Response)都是可以被截获的、篡改、重放(重发)的。因此我们需要考虑以下几点内容: 防伪装攻击(案例:在公共网络环境中,第三方 有意或恶意 的调用我们的接口) 防篡改攻击(案例:在公共网络环境

    2024年02月07日
    浏览(30)
  • 使用 openssl 对文件签名和验签

    这里介绍:文件签名和验签做了什么,openssl 命令行工具进行签名和验签。 文件签名和验签 签名 有文件 test.txt,使用摘要算法(如 SHA256)计算出文件的摘要,再使用私钥(private.pem)对摘要的内容做加密,就叫做文件签名,摘要加密之后的内容叫做文件的签名(记 test.sig)。

    2024年02月11日
    浏览(36)
  • Java应用服务系统安全性,签名和验签浅析

    随着互联网的普及,分布式服务部署越来越流行,服务之间通信的安全性也是越来越值得关注。这里,笔者把应用与服务之间通信时,进行的的安全性相关, 加签 与 验签 ,进行了一个简单的记录。 网关服务接口,暴漏在公网,被非法调用? 增加了token安全验证,被抓包等

    2024年02月13日
    浏览(41)
  • secure boot(三)secure boot的签名和验签方案

    FIT 格式支持存储镜像的hash值,并且在加载镜像时会校验hash值。这可以保护镜像免受破坏,但是,它并不能保护镜像不被替换。 而如果对hash值使用私钥签名,在加载镜像时使用公钥验签则可以保护镜像不被替换。因此,公钥必须保存在一个绝对安全的地方。 接下来的内容要

    2024年02月01日
    浏览(33)
  • QT使用OpenSSL的接口实现RSA2的签名和验签

    加密和签名在RSA加密算法中是两个不同的概念,虽然它们都涉及RSA密钥对的使用,但目的和应用场景有所不同。 加密 (encrypt/decrypt) : 加密 :使用接收方的公钥对数据进行加密,只有拥有相应私钥的接收方才能解密数据。 解密 :使用接收方的私钥对加密数据进行解密,从而获

    2024年02月22日
    浏览(41)
  • RSA加密,解密,加签及验签

    目录 1.说明 2.加密和加签的区别 3.后端加密,解密,加签及验签示例 4.前端加密,解密,加签及验签示例 5.前端加密,后端解密,前端加签,后端验签 6.注意事项 1.说明 RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥

    2024年02月20日
    浏览(57)
  • RSA加密、解密、签名、验签的原理及方法

    一、RSA加密简介 RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大

    2024年02月05日
    浏览(51)
  • springboot + vue 前后端加密传输 RSA互相加解密、加签验签、密钥对生成

    参考 由于Java非对称加解密、加验签都是采用PKCS#8格式的密钥,PKCS#1格式的密钥跑不通,这里先简单介绍一下两者的区别。 PKCS#1和PKCS#8是两个不同的数字证书标准。 PKCS#1是一个公钥加密标准,它定义了使用RSA算法进行加密和签名的格式。主要用于对数字签名、加密以及数字签

    2024年04月27日
    浏览(41)
  • OpenSSL 3.1.1 ECC 加密、解密、签名、验签(国密 sm2、sm3)

    openssl 3 默认废弃了 旧版本 (opessl 1.x) 的部分api 导致部分旧ecc 代码无法使用(可以通过配置编译选项打开) ,这里展示如何使用新接口用ECC 进行加密解密。 新接口是真的方便,基本上你都不需要懂啥密码学知识,对我们这种密码白痴来说太好了 头文件 生成密钥对 导出公

    2024年02月05日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包