• Byronsh博客的数字签名的验证方法


    信息安全主要关注信息的三个重要属性,完整性、保密性、可用性。

    数字签名主要用于确保数据的完整性。

    博主想确保博客的完整性,通过数字签名可以验证博文是否被他人转载后修改了。

    比如有的博文带有“未经许可禁止转载”声明的博文。如果某站未经许可爬了我的博客,同时修改声明为“允许转载”,因为博客园发布的博客可以再编辑,但不支持博客的版本管理,所以我很难证明我从未给出“允许转载”的声明。针对这种情况,数字签名可以给出有效的证据,这是如何做到的呢?首先,博主会对每篇博客做数字签名。如果文章转载后被篡改,数字签名验证会失败。

    当然,数字签名也可以保护转载文章的人。说不定哪天博主不小心把博文许可从“允许转载”改为“未经许可禁止转载”。因为已经被转载的博文带有有效的数字签名,也可以证明博主以前的确给出过“允许转载”的声明,博主自己想耍赖也不行。

    从2019年7月20日开始,采用的签名算法为 SHA384 + ECDSA384。

    数字签名验证过程的几个重点:

    1)正确的公钥也是确保有效数字签名的关键。博主所有博文的数字签名必须使用下面的公钥验证。

    -----BEGIN PUBLIC KEY-----
    MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEsrblD3gHjQKPJHWO0mpzaXhAmN95lrcB
    VS2dC48mPhVBqFoH4MCEudMNJCnRG6FV9zWBeZIlE9wOtksYBNRgZgV/hH0/jzqe
    Ts4Eq6HSS0tzorLTgPnQPNOmd+qPIs3M
    -----END PUBLIC KEY-----
    

    2)博主所有博文只对文本内容进行了数字签名,未对其他多媒体内容进行签名。

    3)验签工具推荐使用基于 javascripthtml博客文本签名和验签工具 (见本文下方)。这个工具也支持生成签名哦。

    4)同样的博客,不同浏览器复制得到的文本可能会不一样,从而导致验签失败。 博主博客的数字签名都是在火狐浏览上生成和测试过的。

    博客文本签名和验签工具

    下面的工具是博主生成签名和验证签名的工具,基于 javascripthtml

    验证签名的步骤 (windows中):

    1) 新建一个文本文件A(以.txt为后缀的文件)

    2) 将下面的代码拷贝到文件A中

    3) 将文件A的后缀从 .txt改为.html

    4) 鼠标双击文件A,用浏览器打开,界面如下(红色文本为添加的注释)。

    5) 博文结尾处带有签名,签名上方会有一条水平分割线。将水平分割线上方的博客正文拷贝到“文本”下面的编辑栏中。(注意:不要拷贝标题和博客结尾处的签名)

    6) 将博文结尾处的签名拷贝到“签名”下的编辑框中

    7) 博主博客验签的公钥已经默认在“公钥”下的编辑框中,保持不变;

    8)对于验证数字签名,“私钥”不起作用,“私钥“下的编辑框保持不变;

    9)点击最下方的按钮“验证签名”,然后会弹出验证结果。

    <!DOCTYPE HTML>
    <html lang="zh-CN">
      <head>
        <meta charset="utf-8">
        <title>数字签名生成/验证</title>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.12/jsrsasign-all-min.js"></script>
    <script>
    
    /* 
     * function generateSignature()
     * 功能: 生成数字签名
     */
    function generateSignature(){
      //1. 获取需要签名的文本
      var plain_text = document.getElementById("input").value;
      //为了减小网页排版导致的签名验证失败,删除所有的空字符(空格,换行符,制表符等等)
      plain_text_trim = plain_text.replace(/s*/g, "");
    
      //2. 用私钥签名
      //2.1 获取公钥 
      var prk = document.getElementById("prk").value;
      var sign_key = KEYUTIL.getKey(prk);
      //2.2 创建签名对象
      let signature = new KJUR.crypto.Signature({alg:"SHA384withECDSA"});
    
      //2.3 初始化签名对象的钥匙和需要签名的文本
      signature.init(sign_key);
      signature.updateString(plain_text_trim);
      //2.4 进行签名
      let a = signature.sign();
      let sign = hextob64(a);
      //2.5 将签名更新进网页的文本框
      document.getElementById("signature").value = sign + "
    --- " + getDateTime();
      
      //3. 提醒用户签名完成
      document.getElementById("result").innerText = getDateTime() + " 签名成功。
    " ;
    };
    
    /* 
     * function verifySignature()
     * 功能: 验证数字签名
     */
    function verifySignature(){
      //1. 获取需要验证数字签名的文本及其签名
      //1.1 获取文本
      var plain_text = document.getElementById("input").value;
      //为了减小网页排版导致的签名验证失败,删除所有的空字符(空格,换行符,制表符等等)
      var plain_text_trim = plain_text.replace(/s*/g, "");
      //1.2 获取签名
      var signature = document.getElementById("signature").value;
      signature = signature.replace(/
    ---s*.*/,""); // remove "--- 2019-09-04"
    
      //2. 用公钥验证签名
      //2.1 获取公钥
      var puk = document.getElementById("puk").value;
      var verify_key = KEYUTIL.getKey(puk);
      //2.2 创建签名对象
      let signatureVf = new KJUR.crypto.Signature({alg:"SHA384withECDSA"}); 
      //2.3 初始化签名对象的钥匙和需要签名的文本
      signatureVf.init(verify_key);
      signatureVf.updateString(plain_text_trim);
      //2.4 验证签名
      let b = signatureVf.verify(b64tohex(signature));
    
      //3. 告知用户验签结果
      if(true == b){
        alert("签名 有效。");
        document.getElementById("result").innerHTML = "<p>" + getDateTime() + "  签名<b style='color:green'>有效</b></p>";
      }
      else{
        alert("签名 无效!!");
        document.getElementById("result").innerHTML = "<p>" + getDateTime() + "  签名<b style='color:red'>无效</b></p>";
      }
    };
    
    function getDateTime()
    {
      var now = new Date();
      var year = now.getFullYear();
      var month = now.getMonth()+1;
      var date = now.getDate();
      var day = now.getDay();
      var hour = now.getHours();
      var minute = now.getMinutes();
      var second = now.getSeconds();
    
      var  dateTime = year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
      return dateTime;
    };
    
    </script>
      </head>    
    
      <body>
        <div>
          <label for="input">文本:</label><br>
          <textarea id="input" name="input"  class=""></textarea><br>
    
          <label for="prk">私钥:</label><br>
          <textarea id="prk" name="prk"  class=""></textarea><br>
    
          <label for="puk">公钥:</label><br>
          <!--下面是用于验证byronsh博客文章数字签名默认公钥-->
          <textarea id="puk" name="puk"  class="">
    -----BEGIN PUBLIC KEY-----
    MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEsrblD3gHjQKPJHWO0mpzaXhAmN95lrcB
    VS2dC48mPhVBqFoH4MCEudMNJCnRG6FV9zWBeZIlE9wOtksYBNRgZgV/hH0/jzqe
    Ts4Eq6HSS0tzorLTgPnQPNOmd+qPIs3M
    -----END PUBLIC KEY-----
          </textarea><br>
    
          <label for="signature">签名:</label><br>
          <textarea id="signature" name="signature"  class=""></textarea><br>
        </div>
    
        <div>
          <button id="btnGenSig" onclick="generateSignature()">生成签名</button>
          <button id="btnVeriSig" onclick="verifySignature()">验证签名</button><br>
        </div>
        <div id="result">
          <p>请点击按钮“验证签名”或“生产签名”</p>
        </div>
      </body>
    </html>
    

    历史

    SHA512 + RSA4096

    在2019年7月20日前,采用SHA512 + RSA4096 签名,其公钥如下。因为签名太长,所以启用了。

    -----BEGIN PUBLIC KEY-----
    MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnrJo0wOPcH+ZeAb+UsGh
    yHhPRiV4sox4aUf2SDHZVfCGUcpZJZQ5pi3QK0lNX4WuaBZ1HquhtU5s7uKqaJlf
    mb1gGCJOG17bHACJV143XR+T7VQe9UmBBp8gpBbEsdYg9+4TJCti8vmDvfz0meJF
    q9De5n9Uk2J2Gt2UQX+dpru8FnDmlI8AIt3eAyfJnY6XB4y9GymuXbyj6R238a6T
    3udc7gK+50CgxVylBO5ANJ9YYDLkGv++9mAODlKXuE/xtG7XNXrTQ0f+NrlrRmDQ
    qCFmAYK8GdT0eKkkT4gHBah7wYEVpw9iOcHzVpajp7vsMe33qO3IpMTFpJ+TkZd9
    H/7gQ6Hu5QPzv236Ym4nLAVtLOxx2iCN2cXT7cmkGas/9oDrYx1TdAW0VSk9PA2H
    KRKZOdy9XYNAN9HOTZcy8YfpLv5CN5OnA+Qpca3XHD3Xf2kYafV0hdMuhBY7EP4y
    yAxQt6Ug+9qWE4jJg5lh6jSbuMdfqO2a2JjZCh5Z4PrX+Cdnh6r1rV7lvSFZmyWY
    gsAuzGh2zip9FY/3Pdy+Y0Xb4PbvNWcc+R8LxF0PrFwwbiYRyC+tGPvUCQIyTHYd
    PMwNqcuxVh2X/WqcK6YVHUmlo6wDsJIMONDPzFTnM4VdhB1KgA5I0awzf6UuGBug
    X44OVTtMBuksYdiydc9wVokCAwEAAQ==
    -----END PUBLIC KEY-----
    

    版权声明:本文为博主原创,允许转载但必须注明原文地址。博客原文:https://www.cnblogs.com/byronsh/p/blog-signature-verification.html


    本文的数字签名如下:

    MGQCMAmQeUELrlFqW+eWW6M1pcIbvmCDQY2BRjWtBfy7fp6dF6fNppHKK4nV7N30TBCorQIwCngoLMtzdI2/1ZvrgNUFYxollXSYHynDk/uc3PwoV9FT7XeebKqxtdYKgfGfM4So
    --- 2019-7-20 9:27:13

    数字签名验证方法

  • 相关阅读:
    防采集策略『blueidea』
    关于进程和线程『整理』
    数据采集『blueidea』
    搜索引擎营销的一些策略『来源:点石互动搜索引擎优化博』
    AJAX之通讯技术简介
    使用AJAX技术构建更优秀的Web应用程序
    AJAX相关JS代码片段和浏览器模型『』
    RDLC报表:每页显示N条记录
    ObjectMapper .NET
    How to Hash Data with Salt
  • 原文地址:https://www.cnblogs.com/byronsh/p/blog-signature-verification.html
Copyright © 2020-2023  润新知