精华内容
下载资源
问答
  • 1.什么是单向散列函数 单向散列函数(one-wayftnction)有一个输入和一个输出,其中输入称为消息,输出称为散列值(hashvalue),单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检测消息的完整性 ...

    1.什么是单向散列函数

    单向散列函数(one-wayftnction)有一个输入和一个输出,其中输入称为消息,输出称为散列值(hashvalue),单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检测消息的完整性

    术语:

    • 消息摘要函数、哈希函数、杂凑函数
    • 输入单向散列函数的消息称为原像(pre-image)
    • 单向散列函数的输出的散列值称为消息摘要(message digest)也称为指纹(fingerprint)
    • 完整性也称为一致性

    性质:

    • 根据任意长度的输入输出为定长
    • 能够快速计算出散列值
    • 消息不同,散列值不同
    • 单向性
    • 强碰撞性

    应用:

    • 检查数据是否被篡改
    • 消息认证码
    • 数字签名
    • 伪随机数生成器
    • 一次性口令

    2.常用的单向散列函数

    1. MD4、MD5(不安全)

    MD4是1990年设计的单向散列函数,能够产生128比特的散列值,不过,随着寻找MD4散列碰撞的方法,现在它已经不安全了

    MD5是1991年设计的单向散列函数,能够产生128比特的散列值

    MD5的强碰撞性已经被攻破,也就是说现在已经能够产生具有相同散列值的两条不同的消息,因此它也不安全了

    1. sha1(不安全)、sha2(目前都安全)

    3.go中使用散列函数

    package main
    
    import (
    	"crypto/sha256"
    	"encoding/hex"
    	"fmt"
    )
    
    func SHA256(){
    	//0.简单的调用(适用于少量数据)
    	sum256 := sha256.Sum256([]byte("sha1(不安全)、sha2(目前都安全)sha1(不安全)、sha2(目前都安全)"))
    	fmt.Printf("hash: %x\n", sum256)
    	//1.初始化一个哈希对象(适用于大文件的数据)
    	hash := sha256.New()
    	//2.添加数据
    	src := []byte("sha1(不安全)、sha2(目前都安全)")
    	hash.Write(src)
    	hash.Write(src) //相当于字符串拼接到一起计算的hash值
    	//3.计算
    	bytes := hash.Sum(nil)
    	//4.转换为字符串
    	str := hex.EncodeToString(bytes)
    	fmt.Println("hash:",str)
    }
    
    func main(){
        SHA256()
    }
    
    展开全文
  • 我们在POSpace(Proof of Space)共识机制下,基于陷门单向函数和新型区块链结构,提出了可修改的区块链方案.只要超过阈值数的节点同意,便可实现区块数据的合法修改,否则不能进行修改.除修改数据外,其余区块数据保持不变...

    实现思路

    通过引入机动因子,重构区块签名子块,在数据失效或错误时,只要超过阈值数节点同意,便可实现区块数据的合法修改,同时保持区块链接不变,除修改数据,其余数据不变,全网仍可按原始验证方式对数据合法性进行验证. 而且,我们设置了特定的阈值,使得修改操作必须经过绝大多数节点同意,恶意的非法修改无法完成,保证了数据的安全。

    相关概念

    陷门单向函数:单向函数是指正向求解容易,但反向求解不可实现的函数。陷门未知时为单向函数,陷门已知时可求逆。

    Grinding Blocks攻击:将交易拆成多份,拿着每份交易去并行计算nonce值

    基于空间证明的区块链:以空间为可信度衡量标准的区块链系统,其共识机制为POSpace,即拥有最大存储空间的节点视为最可信节点,由其完成系统相关操作,获取奖励。通过节点对有向无环图的构造速度来衡量空间大小。空间大的节点存储的标签值多,可直接查找到标签值,而空间小的节点无法存储过多的标签值,需要通过后续计算得到标签值,这样空间小的节点花费的时间就要多。

    基于空间证明的区块链结构
    基于空间证明的区块链结构
    改进后的基于空间证明的区块链结构
    在这里插入图片描述
    机动因子公式
    机动因子公式
    区块链修改过程对比
    区块链修改过程对比

    修改过程

    公式
    已知在这里插入图片描述
    ,即原来区块的交易子块的哈希值与机动因子G结果的签名, 已知在这里插入图片描述
    ,即进行修改后的交易子块的哈希值,通过以上两个已知,计算出在这里插入图片描述
    ,即修改后的机动因子G,使该等式成立,这样一来交易子块虽进行了修改,但签名子块并未发生改变。

    修改流程

    [1]任艳丽,徐丹婷,张新鹏,谷大武.可修改的区块链方案[J].软件学报,2020,31(12):3909-3922.

    展开全文
  • 一文搞懂单向散列函数

    千次阅读 2021-09-27 09:50:28
    单向散列函数(one-way hash function)是指对不同的输入值,通过单向散列函数进行计算,得到固定长度的输出值。这个输入值称为消息(message),输出值称为散列值(hash value)。 单向散列函数也被称为消息摘要...

    微信搜索:码农StayUp
    主页地址:https://gozhuyinglong.github.io
    源码分享:https://github.com/gozhuyinglong/blog-demos

    1. 定义

    单向散列函数(one-way hash function)是指对不同的输入值,通过单向散列函数进行计算,得到固定长度的输出值。这个输入值称为消息(message),输出值称为散列值(hash value)。

    单向散列函数

    单向散列函数也被称为消息摘要函数(message digest function)、哈希函数或者杂凑函数。输入的消息也称为原像(pre-image)。输出的散列值也称为消息摘要(message digest)或者指纹(fingerprint),相当于该消息的身份证。

    单向散列函数有多种实现算法,常见的有:MD5SHA-1SHA-2SHA-3

    2. 特性

    通过上面的定义,我们对单向散列函数的了解还是模糊的。下面介绍单向散列函数的特性,加深一下印象。

    2.1 散列值长度固定

    无论消息的长度有多少,使用同一算法计算出的散列值长度总是固定的。比如 MD5 算法,无论输入多少,产生的散列值长度总是 128 比特(16字节)。

    然而比特是计算机能够识别的单位,而我们人类更习惯于使用十六进制字符串来表示(一个字节占用两位十六进制字符)。

    散列值长度固定

    2.2 消息不同其散列值也不同

    使用相同的消息,产生的散列值一定相同。

    使用不同的消息,产生的散列值也不相同。哪怕只有一个比特的差别,得到的散列值也会有很大区别。

    这一特性也叫做抗碰撞性,对于抗碰撞性弱的算法,我们不应该使用。

    消息不同其散列值也不同

    2.3 具备单向性

    只能通过消息计算出散列值,无法通过散列值反算出消息。

    具备单向性

    2.4 计算速度快

    计算散列值的速度快。尽管消息越长,计算散列值的时间也越长,但也会在短时间内完成。

    3. 常见算法

    MD5 与 SHA-1 算法已被攻破,不应该被用于新的用途;SHA-2 与 SHA-3 还是安全的,可以使用。

    SHA-2包括:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。

    SHA-3包括:SHA3-224、SHA3-256、SHA3-384、SHA3-512。

    算法名称散列值长度是否安全
    MD5128不安全
    SHA-1160不安全
    SHA-224224安全
    SHA-256256安全
    SHA-384384安全
    SHA-512512安全
    SHA-512/224224安全
    SHA-512/256256安全
    SHA3-224224安全
    SHA3-256256安全
    SHA3-384384安全
    SHA3-512512安全

    4. 应用场景

    单向散列函数并不能确保信息的机密性,它是一种保证信息完整性的密码技术。下面来看它的应用场景。

    4.1 用户密码保护

    用户在设置密码时,不记录密码本身,只记录密码的散列值,只有用户自己知道密码的明文。校验密码时,只要输入的密码正确,得到的散列值一定是一样的,表示校验正确。

    为了防止彩虹表破解,还可以为密码进行加盐处理,只要验证密码时,使用相同的盐即可完成校验。

    用户密码保护

    使用散列值存储密码的好处是:即使数据库被盗,也无法将密文反推出明文是什么,使密码保存更安全。

    4.2 接口验签

    为了保证接口的安全,可以采用签名的方式发送。

    发送者与接收者要有一个共享秘钥。当发送者向接收者发送请求时,参数中附加上签名(签名由共享秘钥 + 业务参数,进行单向散列函数加密生成)。接收者收到后,使用相同的方式生成签名,再与收到的签名进行比对,如果一致,验签成功。

    这样即可以验证业务参数是否被篡改,又能验明发送者的身份。

    接口验签

    4.3 文件完整性校验

    文件被挂载到网站时,同时也附上其散列值和算法,比如 Tomcat 官网。

    Tomcat官网下载页面

    用户下载后,计算其散列值,对比结果是否相同,从而校验文件的完整性。

    4.4 云盘秒传

    当我们将自己喜欢的视频放到网盘上时,发现只用了几秒的时间就上传成功了,而这个文件有几个G大小,是怎么做到的呢?

    其实这个“秒传”功能可以利用单向散列函数来实现。

    当我们上传一个文件时,云盘客户端会先为该文件生成一个散列值。拿着这个散列值去数据库中匹配,如果匹配到,说明该文件已经在云服务器存在。只需将该散列值与用户进行关联,便可完成本次“上传”。

    这样,一个文件在云服务器上只会存一份,大大节约了云服务器的空间。

    云盘秒传

    5. 代码实现

    JDK的 java.security.MessageDigest 类为我们提供了消息摘要算法,用于 MD5和SHA的散列值生成。下面代码做了简单的封装,便于直接使用。

    public class MDUtil {
    
        /**
         * MD5 加密
         *
         * @param data 要加密的数据
         * @return 32位十六进制字符串
         */
        public static String MD5(byte[] data) {
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                byte[] bytes = md.digest(data);
                return bytesToHexString(bytes);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * MD5 加密
         *
         * @param data 要加密的数据
         * @return 32位十六进制字符串
         */
        public static String MD5(String data) {
            return MD5(data.getBytes());
        }
    
        /**
         * SHA-1 加密
         *
         * @param data 要加密的数据
         * @return 40位十六进制字符串
         */
        public static String SHA1(byte[] data) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                byte[] bytes = md.digest(data);
                return bytesToHexString(bytes);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * SHA-1 加密
         *
         * @param data 要加密的数据
         * @return 40位十六进制字符串
         */
        public static String SHA1(String data) {
            return SHA1(data.getBytes());
        }
    
        /**
         * SHA-224 加密
         *
         * @param data 要加密的数据
         * @return 56位十六进制字符串
         */
        public static String SHA224(byte[] data) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-224");
                byte[] bytes = md.digest(data);
                return bytesToHexString(bytes);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * SHA-224 加密
         *
         * @param data 要加密的数据
         * @return 56位十六进制字符串
         */
        public static String SHA224(String data) {
            return SHA224(data.getBytes());
        }
    
        /**
         * SHA-256 加密
         *
         * @param data 要加密的数据
         * @return 64位十六进制字符串
         */
        public static String SHA256(byte[] data) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                byte[] bytes = md.digest(data);
                return bytesToHexString(bytes);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * SHA-256 加密
         *
         * @param data 要加密的数据
         * @return 64位十六进制字符串
         */
        public static String SHA256(String data) {
            return SHA256(data.getBytes());
        }
    
        /**
         * SHA-384 加密
         *
         * @param data 要加密的数据
         * @return 96位十六进制字符串
         */
        public static String SHA384(byte[] data) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-384");
                byte[] bytes = md.digest(data);
                return bytesToHexString(bytes);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * SHA-384 加密
         *
         * @param data 要加密的数据
         * @return 96位十六进制字符串
         */
        public static String SHA384(String data) {
            return SHA384(data.getBytes());
        }
    
        /**
         * SHA-512 加密
         *
         * @param data 要加密的数据
         * @return 128位十六进制字符串
         */
        public static String SHA512(byte[] data) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-512");
                byte[] bytes = md.digest(data);
                return bytesToHexString(bytes);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * SHA-512 加密
         *
         * @param data 要加密的数据
         * @return 128位十六进制字符串
         */
        public static String SHA512(String data) {
            return SHA512(data.getBytes());
        }
    
        /**
         * 将字节数组转换为十六进制字符串
         *
         * @param bytes 字节数组
         * @return 十六进制字符串
         */
        private static String bytesToHexString(byte[] bytes) {
            StringBuilder hexValue = new StringBuilder();
            for (byte b : bytes) {
                int val = b & 0xFF;
                if (val < 16) {
                    hexValue.append("0");
                }
                hexValue.append(Integer.toHexString(val));
            }
            return hexValue.toString();
        }
    
    }
    

    下面分别使用这些算法计算“123456”的散列值:

    public static void main(String[] args) {
        System.out.println("MD5\t\t" + MDUtil.MD5("123456"));
        System.out.println("SHA-1\t" + MDUtil.SHA1("123456"));
        System.out.println("SHA-224\t" + MDUtil.SHA224("123456"));
        System.out.println("SHA-256\t" + MDUtil.SHA256("123456"));
        System.out.println("SHA-384\t" + MDUtil.SHA384("123456"));
        System.out.println("SHA-512\t" + MDUtil.SHA512("123456"));
    }
    

    输出结果:

    MD5      e10adc3949ba59abbe56e057f20f883e
    SHA-1    7c4a8d09ca3762af61e59520943dc26494f8941b
    SHA-224  f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6
    SHA-256  8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
    SHA-384  0a989ebc4a77b56a6e2bb7b19d995d185ce44090c13e2984b7ecc6d446d4b61ea9991b76a4c2f04b1b4d244841449454
    SHA-512  ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
    

    我用的是Java8,还不支持 SHA-3,所以上面代码只封装了MD5、SHA-1和SHA-2。

    Java8支持的算法

    从Java9开始支持SHA-3

    Java9支持的算法

    6. 完整代码

    完整代码请访问我的Github,若对你有帮助,欢迎给个Star,谢谢!

    https://github.com/gozhuyinglong/blog-demos/blob/main/java-source-analysis/src/main/java/io/github/gozhuyinglong/utils/MDUtil.java

    7. 推荐阅读

    展开全文
  • Python单链表及函数功能代码实现 Python单链表及函数功能代码实现 #代码实现单向链表by Fan class Node(object): # 节点,数据区加链接区 def __init__(self,elem): self.elem = elem self.next = None class ...

    Python单链表及函数功能代码实现

    Python单链表及函数功能代码实现

    #代码实现单向链表by Fan
    class Node(object):
        # 节点,数据区加链接区
        def __init__(self,elem):
            self.elem = elem
            self.next = None
    
    class SingleLinkList(object):
        #单向链表,定义头
        def __init__(self,node = None):
            self._head = node
        #判断链表是否为空
        def is_empty(self):
            print(self._head == None)
        #获取链表的长度
        def length(self):
            cur = self._head
            count = 0
            while cur != None:
                cur = cur.next
                count += 1
            return count
        #遍历链表
        def travel(self):
            cur = self._head
            while cur != None:
                print(cur.elem,end="")
                cur = cur.next
        #头部插入
        def add(self,item):
            node = Node(item)
            node.next = self._head
            self._head = node
        #尾部插入
        def append(self,item):
            node = Node(item)
            if self._head == None:
                self._head = node
            else:
                cur = self._head
                while cur.next != None:
                    cur = cur.next
                cur.next = node
        #指定位置插入
        def insert(self,pos,item):
            if pos < 1:
                self.add(item)
            elif pos > self.length()-1:
                self.append(item)
            else:
                node = Node(item)
                pre = None
                cur = self._head
                count = 0
                while count < pos:
                    pre = cur
                    cur = cur.next
                    count += 1
                pre.next = node
                node.next = cur
        #查找特定元素是否存在
        def search(self,item):
            cur = self._head
            while cur != None:
                if cur.elem == item:
                    print("在")
                    return True
                else:
                    cur = cur.next
            print("不在")
            return False
        #删除某个特定元素
        def shanchu(self,item):
            pre = None
            cur = self._head
            while cur != None:
                if cur.elem == item:
                    #判断该节点是否为头节点
                    if cur == self._head:
                        self._head = cur.next
                        return True
                    else:
                        pre.next = cur.next
                        return True
                else:
                    pre = cur
                    cur = cur.next
            return False
    
        #删除某个位置的元素
        def delete(self,pos):
            pre = None
            cur = self._head
            i = 0
            j = 0
            if cur == None:
                print("删除请求不合法")
            elif pos == 0:
                self._head = cur.next
            else:
                if pos > self.length() - 1:
                    print("删除请求不合法")
                else:
                    while i <= pos:
                        if j < pos:
                            pre = cur
                            cur = cur.next
                            j += 1
                        else:
                            pre.next = cur.next
                        i += 1
    

    新手上路,欢迎指导!

    展开全文
  • 关于术语不同的参考书使用的术语有所不同:单向散列函数(one-way hash function)、消息摘要函数(message digest function)、哈希函数、杂凑函数输入的是消息(message)也称为原像(pre-image)输出的是散列值(hash ...
  • MAC和单向Hash函数一样,但是包括了一个密钥,只有拥有密钥的人才能鉴别这个hash函数,所以消息认证码MAC提供的可鉴别性是很有用的。 因为不同的钥匙会产生不同的Hash函数,如果钥匙t和消息x改变了都无法得到正确的...
  • 单向散列函数及案例

    2021-11-02 14:54:55
    单向散列函数(one-way hash function),又称单向Hash函数、杂凑函数。有一个输入和一个输出,输入的数据称为消息(message),输出的数据称为散列值(hash value)。单向散列函数可以根据消息的内容计算出散列值,...
  • } 错误原因: C语言函数的传递是单向传递的,就相当于,main函数的p1,p2将a,b的地址传递给了形参p1,p2,但swap函数里的形参p1,p2是一个新的内存地址,和main函数里的p1,p2内存地址不同,属于两个不同的指针,在swap...
  • 密码体制有哪五部分

    2021-07-21 01:56:49
    单向函数只适用于某些特殊的、不需要解密的应用场合,如用户的口令存储或信息的完整性保护与鉴别等。 (2)双向变换密码体制是指能够进行可逆的加密、解密变换,它要求所使用的密码算法能够进行可逆的双向加解密变换。 5...
  • 因为socket是双向,client和server都可以进行input和output,所以有时候我们需要数据在socket上实现单向的传输,即数据往一个方向传输。单向的socket为半开放Socket。 要实现半开放式,需要用到shutdown()函数。 ...
  • 递归( recursion)是一种神奇的...和递归相关的概念里,线性递归/非线性递归、单向递归/非单向递归,是非常重要的,要想掌握递归技术,就必须要深入理解。关于递归的基本概念,有兴趣的读者,可以参考我的博客《Pytho...
  • 单向函数 单向函数(One-way function)是一种具有下述特点的单射函数:对于每一个输入,函数值都容易计算(多项式时间);但是对于一个随机的函数值,算出其对应的输入却比较困难(无法在多项式时间内使用确定型...
  • 本题要求实现一个将输入的学生成绩组织成单向链表的简单函数函数接口定义:void input(); 该函数利用scanf从输入中获取学生的信息,并将其组织成单向链表。链表节点结构定义如下: struct stud_node { int num; /...
  • 写一个函数建立一个有3名学生数据的单向动态链表。解:程序:#include#include#define LEN sizeof(struct Student)struct Student{long num;float score;struct Student *next;};int n;struct Student *creat(void)/...
  • 单向散列函数 文章目录单向散列函数前言单向散列函数原理1.场景举例2.函数性质3.函数应用实现方法1.MD算法家族2.SHA算法家族SHA2561.预处理2.哈希计算mbedtls示例1.接口描述 前言 我本人是一名物联网代码搬运工,...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼float main(){int x=2,y=3,z=0;...//调用函数,并通过值传递方式传递参数,实际上就是复制了一份参数的值过去给被 调函数printf("(4)x=%d y=%d z=%d\n",x,y,z);//由于...
  •   要解决上述问题就需要用到单向散列函数单向散列函数相当于为数据增加一个数据指纹,我们使用一个函数计算出数据的指纹,这个指纹是独一无二的,相同数据生成指纹相同,不同数据生成指纹不同(即使一小点改动...
  • C语言单向链表的实现

    2021-05-22 09:44:45
    采用VS2013编辑器编写的C语言单向链表代码:#include #include typedef int TypeData;#define NODE_LENGTH sizeof(NODE)/**定义链表的结构体*/typedef struct tagNode{TypeData tdData;struct tagNode *plNext;}NODE...
  • #include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> struct Student { long num; float score; struct Student *next; }; int n; struct Student *creat......
  • #include#include #include #include #include #include #include #include#include#include using namespace std;//链表的数据结构struct ListNode{int value;...//赋值构造函数ListNode (int v) : v...
  • 下面来写一些简单的接口函数 先定义一个链表 //重定义 typedef int DataType; struct SListNode { DataType data; struct SListNode* next; }; //重定义 typedef struct SListNode SLTNode; 链表的输出函数 ...
  • #include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct Student) struct Student { long num; float score; struct Student *next; }; int n; struct Student *creat(void) ...p1 = p2 = (struc
  • 信息安全概论作业题(精简版)

    千次阅读 2020-12-21 13:51:50
    答:数字签名就是通过一个单向函数对要传送的报文进行处理得到的用以认证报文来源并核实报文是否发生变化的一个字母数字串,该字母数字串被成为该消息的消息鉴别码或消息摘要,这就是通过单向哈希函数实现的数字签名...
  • 代码: #include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct Student) struct Student{ long num; float score; struct Student *next; }; int n; struct Student * creat... p1=p2=
  • 单向散列函数(Hash)

    2021-12-01 10:26:30
    Hash函数的性质 常用Hash函数:MD5(128bit)、SHA-1(160bit)等。 1. 使用Hash函数进行完整性验证的模型 2. 使用Hash函数进行口令验证(1) 3. 使用Hash函数进行口令验证(2) 4. 使用Hash解决数字签名问题 5. 使用...
  • 哈希函数和消息认证

    千次阅读 2020-12-29 21:39:24
    文章目录一、哈希(Hash)函数1、Hash函数的概念2、Hash函数结构3、Hash函数的应用二、Hash算法1、MD5算法2、SHA1算法三、Hash函数的攻击1、生日悖论:四、消息论证1、消息认证基础理论2、消息认证码3、基于DES的消息...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 128,700
精华内容 51,480
关键字:

单向函数