基于SHA-256的HMAC文件校验器

基于SHA-256的HMAC文件校验器

作者:Gamsn

下载源代码

  HMAC即带密钥的HASH函数,用它产生的报文鉴别码(MAC)可以实现报文鉴别。这里我将其做成一个软件,用于对文件的合法性进行校验。以下我先简单介绍软件相关背景知识再介绍其代码实现。

一、背景知识简介
  有时候进行通信的双方基于安全的考虑需要对对方发过来的消息进行校验,以确定消息是未经第三方修改过的。这种校验可以这样进行:
  • 双方共同约定一个密钥(即一个密码),这个密钥是对第三方保密的;
  • 消息的发方使用该密钥对将发送的消息产生一个校验码,并把该校验码附在消息后一起发出;
  • 消息的接收方在接收到附有校验码的消息后,将消息和校验码分开,用密钥对该消息生成一个校验码;
  • 然后将两个校验码相比较,如果相同的话则说明消息是未经第三方修改的,如果不同的话说明消息很可能被非法修改过(当然也有可能是别的原因使消息改变了)则该消息不可信,需要对方重发 ;
  •  *其中,生成校验码的算法一般采用HMAC,它保证了第三方在不知密钥的情况下,不可能在修改消息后可以同时修改校验码使之与修改后的消息匹配。
     *在整个过程中消息是公开的(未经加密的),算法只提供消息的完整性校验而不提供保密性,保密性可由公钥加密算法现实,这里不作讨论。

    二、软件的实现
      我做的该软件是可以对电脑磁盘上的任意一文件生成一校验文件.vri(密钥由用户自己输入),根据该校验文件可以在需要之时对相应的文件进行校验。具体做法将在后面的例子中给出。
      程序中的HMAC算法的HASH函数我采用的是SHA-256算法,它比起MD5和SHA-1来要安全。(其实因为不是正式的安全产品,所以在本程序中采用MD5或SHA-1也未尝不可)。

    *HMAC的结构如下图所示:
     


    图一 HMAC的结构

    图中各符号定义如下:

    IV =作为HASH函数输入的初始值 
    M  =HMAC的消息输入 
    Yi =M的第i个分组,0<=i<=(L-1) 
    b  =每一分组所含的位数 
    n  =嵌入的HASH函数所产生的HASH码长 
    K  =密钥 
    K+ =为使K为b位长而在K左边填充0后所得的结果 
    ipad =0x36重复b/8次的结果 
    opad =0x5c重复b/8次的结果 

      对于特定的HASH函数,b、n都是固定的,所以在程序的HMAC类中,n被定义为宏Mn,b被定义为Mb,值分别为32和64。由于该结构的效率较低,不利于实用化。于是有人提出了一个HMAC的高效实现方案。

    *HMAC的有效实现方案如下:


    图二 HMAC的有效实现方案

    其中的HASH即为SHA-256。

    图中左边所示为预计算,右边为对每条消息的计算。在密钥不变的情况下只需进行一次预计算,以后在产生校验码时就只用到右边的计算了。这样就可以提高效率。
      需要说明的是,大家在阅读我写的HMAC的类可能会发现,在每次计算时都进行了左右两边的计算(不论密钥怎样)。这是因为我考虑到个人用户可能会不时地对密钥进行更换,并且应用场合也不对效率有特别的要求。当然这样做并没有体现出HMAC有效实现方案的优点。
      另外还有一点就是我对密钥的填充是填充的低位,即密钥右边,这和上述方案有不同(方案上说是要填充在高位,即左边),在此说明,以使大家在看源代码的时候不至于疑惑。
      以上有效实现方案在HMac类中现实,HASH函数sha-256在Sha256类中实现。由于这里主要说的是HMAC,sha-256只是作为一个黑盒子,所以不多解释。
      程序中的Mac类与HAMC和HASH函数都无关,只是一个存放结果的介质,它甚至都没有成员函数,我也在考虑是不是可以不把它做成一个类。

    为了便于读者阅读HMac类中的各变量基本上采用图二中的各标识符标识。

    对于下面一段代码读者可能会有疑惑,明明是该得到第一个预计算的结果,m_dwA1—m_dwH1是什么呢?

    for(i=0;i<Mb;i++) 
       S[i]=sKeyplus[i]^ipad[i];
    m_sha256.Init(Mb);
    m_sha256.GenW(S,Mb);
    m_sha256.Steps();
    m_dwA1=m_sha256.OA;
    m_dwB1=m_sha256.OB;
    m_dwC1=m_sha256.OC;
    m_dwD1=m_sha256.OD;
    m_dwE1=m_sha256.OE;
    m_dwF1=m_sha256.OF;
    m_dwG1=m_sha256.OG;
    m_dwH1=m_sha256.OH;	   
      其实m_dwA1—m_dwH1就是第一个预计算的输出。这里因为这个输出有256位,于是我把它拆成了8个32位。同理,第二个预计算的输出为m_dwA2—m_dwH2。
      此外,程序中关于文件拖放和文件保存打开的部分(包括串行化等)对于初学者来说都是一个不错的借鉴,当然高手就不需在意了。下面将给出一个例子使读者的认识感性化一点。

    三、例子

    我有一张非常重要的图片传给你,如下:


    图三 例图 VeriFileimg3

    在传这张图的同时附上它的校验文件“important.vri”。(该校验文件在源代码压缩包)

    而你收到的图片如下:(它在传送中在8,46处被非法的第三方修改了一个象素)


    图四 例图VeriFileimg4

    你用该软件对其进行校验可以如下操作:
    1. 运行该软件,打开important.vri(打开方式有两种,你可以从菜单‘文件-打开’中打开,也可以直接把文件拖进程序窗口中。)
      (第一次运行该软件后,程序会创建一个对vri文件的关联,以后打开vri文件就能以双击vri文件打开了。);
    2. 将要校验的文件拖入程序窗口中,在弹出的对话框中选否;或者是从菜单‘校验文件-验证源文件’中打开;
    3. 然后程序要求输入校验密钥,这里你和我约定的密钥为gamsn,也就是输入gamsn;
    4. 程序会计算源文件的校验码值,并告诉你结果;

      由源文件生成校验文件的操作也很简单,从菜单‘校验文件-生成校验文件’中选中你的源文件,然后在弹出的对话框中输入密钥就可以了。提醒一下,密钥最大有效长度为16字节,中英文不限。生成的校验文件都自动以vri为后缀名。

    四、结束语

    大概情况就是如此,大家有什么问题或指正可以与我联系,谢谢!  另外如果诸君对HASH函数感兴趣的话可以参考 William Stallings 的 Cryptography and Network Security Principles and Practices 一书第三版。该书不是编程方面的指南,而是密码与网安方面的专业教材。它的中文版也译得不错,是一本好书。 

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple 最新软件的错误和性能问题。
    欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只有5%的概率会遇到选择运营商界面且部分必须连接到iTunes才可以激活
    一般在接外包的时候, 通常第三方需要安装你的app进行测试(这时候你的app肯定是还没传到app store之前)。
    前言为了让更多的人永远记住12月13日,各大厂都在这一天将应用变灰了。那么接下来我们看一下Flutter是如何实现的。Flutter中实现整个App变为灰色在Flutter中实现整个App变为灰色是非常简单的,只需要在最外层的控件上包裹ColorFiltered,用法如下:ColorFiltered(颜色过滤器)看名字就知道是增加颜色滤镜效果的,ColorFiltered( colorFilter:ColorFilter.mode(Colors.grey, BlendMode.
    flutter升级/版本切换
    (1)在C++11标准时,open函数的文件路径可以传char指针也可以传string指针,而在C++98标准,open函数的文件路径只能传char指针;(2)open函数的第二个参数是打开文件的模式,从函数定义可以看出,如果调用open函数时省略mode模式参数,则默认按照可读可写(ios_base:in | ios_base::out)的方式打开;(3)打开文件时的mode的模式是从内存的角度来定义的,比如:in表示可读,就是从文件读数据往内存读写;out表示可写,就是把内存数据写到文件中;
    文章目录方法一:分别将图片和文字置灰UIImage转成灰度图UIColor转成灰度颜色方法二:给App整体添加灰色滤镜参考App页面置灰,本质是将彩色图像转换为灰度图像,本文提供两种方法实现,一种是App整体置灰,一种是单个页面置灰,可结合具体的业务场景使用。方法一:分别将图片和文字置灰一般情况下,App页面的颜色深度是24bit,也就是RGB各8bit;如果算上Alpha通道的话就是32bit,RGBA(或者ARGB)各8bit。灰度图像的颜色深度是8bit,这8bit表示的颜色不是彩色,而是256
    领导让调研下黑(灰)白化实现方案,自己调研了两天,根据网上资料,做下记录只是学习过程中的记录,还是写作者牛逼
    让学前端不再害怕英语单词(二),通过本文,可以对css,js和es6的单词进行了在逻辑上和联想上的记忆,让初学者更快的上手前端代码
    用Python送你一颗跳动的爱心
    在uni-app项目中实现人脸识别,既使用uni-app中的live-pusher开启摄像头,创建直播推流。通过快照截取和压缩图片,以base64格式发往后端。
    商户APP调用微信提供的SDK调用微信支付模块,商户APP会跳转到微信中完成支付,支付完后跳回到商户APP内,最后展示支付结果。CSDN前端领域优质创作者,资深前端开发工程师,专注前端开发,在CSDN总结工作中遇到的问题或者问题解决方法以及对新技术的分享,欢迎咨询交流,共同学习。),验证通过打开选择支付方式弹窗页面,选择微信支付或者支付宝支付;4.可取消支付,放弃支付会返回会员页面,页面提示支付取消;2.判断支付方式,如果是1,则是微信支付方式。1.判断是否在微信内支付,需要在微信外支付。
    Mac命令行修改ipa并重新签名打包
    首先在 iOS 设备中打开开发者模式。位于:设置 - 隐私&安全 - 开发者模式(需重启)
    一 现象导入MBProgressHUD显示信息时,出现如下异常现象Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_MBProgressHUD", referenced from: objc-class-ref in ViewController.old: symbol(s) not found for architecture x86_64clang: error: linker command failed wit
    Profiles >> 加号添加 >> Distribution >> "App Store" >> 选择 2.1 创建的App ID >> 选择绑定 2.3 的发布证书(.cer)>> 输入描述文件名称 >> Generate 生成描述文件 >> Download。Certificates >> 加号添加 >> "App Store and Ad Hoc" >> “Choose File...” >> 选择上一步生成的证书请求文件 >> Continue >> Download。
    今天有需求,要实现的功能大致如下:在安卓和ios端实现分享功能可以分享链接,图片,文字,视频,文件,等欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~声明:本博文章若非特殊注明皆为原创原文链接。