头歌—密码学基础

2023-12-05

第1关:哈希函数

题目

任务描述

本关任务:利用哈希算法统计每个字符串出现的个数。

相关知识

为了完成本关任务,你需要掌握:1.密码学哈希函数的概念及特性,2.安全哈希算法。

密码学哈希函数的概念及特性

我们需要理解的第一个密码学的基础知识是密码学哈希函数,哈希函数是一个数学函数,具有以下三个特性: ● 其输入可为任意大小的字符串。 ● 它产生固定大小的输出。为使本章讨论更具体,我们假设输出值大小为 256 位,但是,我们的讨论适用于任意规模的输出,只要其足够大。 ● 它能进行有效计算,简单来说就是对于特定的输入字符串,在合理时间内,我们可以算出哈希函数的输出。更准确地说,对应n位的字符串,其哈希值计算的复杂度为 O(n) 。 这些特性定义了一般哈希函数,以这个函数为基础,我们可以创建数据结构,例如哈希表。我们将只专注于加密的哈希函数,要使哈希函数达到密码安全,我们要求其具有以下三个附加特性:

  1. 碰撞阻力( collision−resistance
  2. 隐秘性( hiding
  3. 谜题友好( puzzle−friendliness

下面具体阐述这三个特性

  • 特性1:碰撞阻力 加密的哈希函数的第一个特性是它要具有碰撞阻力。这里的碰撞指对于两个不同的输入,产生相同的输出。如果对于哈希函数 H(⋅) ,没有人能够找到碰撞,我们则称该函数具有碰撞阻力。即: 如果无法找到两个值, x y x\\=y ,而 H(x)=H(y) ,则称哈希函数 H 具有碰撞阻力
  • 特性2:隐秘性 我们希望哈希函数拥有的第二个特性是其隐秘性。隐秘性保证,如果我们仅仅知道哈希函数的输出 y=H(x) ,我们没有可行的办法算出输入值 x 。问题是,上述的表示形式不一定是正确的。考虑以下简单的例子:我们做一个抛硬币的实验,如果抛硬币结果为正面,我们会宣布字符串哈希为“正面”;如果结果为反面,我们会宣布字符串哈希为“反面”。 然后我们问我们的对手,在他没有见到抛硬币,而只见到哈希函数的输出的前提下说出哈希函数的输入字符串。为了回答问题,对手会简单计算“正面”字符串的哈希值及“反面”字符串的哈希值,然后对手便可以知道他得到的是哪一个。这样,只需要几步,对手就能反解出输入值。 对手能够猜出字符串,这是因为 x 只有两个可能,他可以很轻易地将两个可能对应的哈希值计算出来。为了能够实现隐秘性,我们需要x的取值来自一个非常广泛的集合,也就是说,仅仅通过尝试几个特定的 x ,就能找到输出值的方式将不会发生了。 现在的问题是:在类似抛硬币的“正面”、“反面”实验中,如果我们想要的反解的输入值并非来自分散的集合,我们是否还能得到隐秘性?幸运的是,对于这个问题答案是肯定的!我们甚至能够通过与另一个较为分散的输入进行结合,而将一个并不分散的输入进行隐秘。现在我们可以更精确地表示隐秘的含义了(双竖线 为连接符号,代表把一系列事件、事情等联系起来)。即: 哈希函数H具有隐秘性,如果:当其输入 r 选自一个高阶最小熵( highmin−entroy )的概率分布,在给定 H(r‖x) 条件下来确定 x 是不可行的
  • 特性3:谜题友好 哈希函数需要的第三个安全特性为谜题友好特性。这一特性较为复杂,我们首先解释该特性的技术要求,然后通过举例来阐释该特性的意义。 直觉上,谜题友好可以这样解释,如果有一个人想找到 y 值所对应的输入,假定在输入集合中,有一部分是非常随机的,那么他将非常难以求得 y 值对应的输入。即: 如果对于任意 n 位输出值 y ,假定k选自高阶最小熵分布,如果无法找到一个可行的方法,在比 2n 小很多时间内找到 x ,保证 H(k‖x)=y 成立,那么我们称哈希函数 H 为谜题友好。
安全哈希算法

安全哈希算法( SecureHashAlgorithm256 ,简称 SHA−256 )。哈希函数有很多,但 SHA−256 是一个主要被比特币世界采用,并且效果还很不错的哈希函数。 回想一下,我们要求哈希函数可以用于任意长度输入。幸运的是,只要我们能建立一个用于固定长度输入的哈希函数,然后通过一般方法,就可以将接受固定长度的哈希函数转化为可接受任意长度输入的哈希函数,我们称这个转换过程为 MD Merkle−Damgard )变换, SHA−256 是采用这种变换方法的常用哈希函数之一。在通用术语中,这种基础型,可用于固定长度,具备碰撞阻力的哈希函数被称为是压缩函数( compressionfunction )。经过验证,如果基本压缩函数具有碰撞阻力的特性,那么经过转换而生成的哈希函数也具有碰撞阻力。 MD 变换很简单。比如压缩函数代入长度为 m 的输入值,并产生长度短一些为 n 的输出值。哈希函数的输入(可为任意大小)被分为长度为 m−n 的区块。 MD 变换运作过程如下:将每个区块与之前区块的输出一起代入压缩函数,注意,输入长度则变为 (m−n)+n=m ,也刚好就是压缩函数的输入长度。对于第一个区块而言,之前没有的区块,我们需要选取一个初始向量。每次调用哈希函数,这个数字都会被再一次使用,而在实践中,你可以直接在标准文档中找到它。最后一个区块的输出也就是你返回的结果。 SHA−256 函数利用了这样的一个压缩函数,这个压缩函数把一个 768 位的输入压缩成一个 256 位的输出,每一个区块的大小是 512 位。

编程要求

根据提示,在右侧编辑器补充代码,输出每个字符串的次数,具体格式看样例,输出按照字符串的字典序从小到大输出。

测试说明

平台会对你编写的代码进行测试:

测试输入:

 5 a ab abc a ab

预期输出:

 a 2 ab 2 abc 1

提示: 可以使用 map<string,int>

代码

用map统计一下每个字符串出现的次数即可。

#include<bits/stdc++.h>
using namespace std;
//在下面Begin和End之间补全代码
/*********** Begin ***********/
int main()
{
    int n;
    cin>>n;
    string x;
	map<string, int> mp;
    for(int i=0; i<n; i++)
    {
        cin>>x;
        auto it = mp.find(x);
        if (it != mp.end()) { // 键存在
        	mp[x] = mp[x] + 1;
		} else {
			mp[x] = 1;
		}
    }
    
    for (auto i : mp) {
    	cout << i.first << " " << i.second << endl;
	}
    return 0;
}
/*********** End ***********/

第2关:数字签名

题目

任务描述

本关任务:对给定的身份以及消息进行数字签名。

相关知识

为了完成本关任务,你需要掌握:1.数字签名的概念和性质,2.公钥即身份。

数字签名的概念和性质

数字签名是密码学中的第二个重要部分。数字签名被认为是对纸上手写签名的数字模拟。我们对数字签名有两个特性要求,使其与我们对手写签名的预期一致。

  • 第一,只有你可以制作你自己的签名,但任何看到它的人都可以验证其有效性;
  • 第二,我们希望签名只与某一特定文件发生联系,因此该签名不能用于表明你同意或支持另一份不同的文件。

对于手写签名来说,第二条就如同确保别人不能将你的签名从一份文件上剪下来,贴到另一份文件的末尾那样。 那我们如何通过密码学来构建这些性质呢?首先,让我们把之前的直观讨论说得更具体一些,以便今后可以更好地论证数字签名方案,并讨论其安全特性。 数字签名方案

(1)数字签名方案由以下三个算法构成: ● (sk,pk):=generateKeys(keysize)``generateKeys 方法把 keysize 作为输入,来产生一对公钥和私钥。私钥 sk 被安全保存,并用来签名一段消息;公钥 pk 是人人都可以找到的,拿到它,就可以用来验证你的签名。 ● sig:=sign(sk,message) 签名过程是把一段消息和私钥作为一个输入,对于消息输出是签名。 ● isValid:=verify(pk,message,sig) 验证过程是通过把一段消息和签名消息与公钥作为输入,如果返回的结果是真,证明签名属实;如果返回的结果为假,证明签名消息为假。 (2)我们要求以下两个性质有效: ● 有效签名可以通过验证,即: verify(pk,message,sign(sk,message))==true ● 签名不可伪造。

公钥即身份

让我们来看一下与数字签名并行的一个有用技巧,基本想法是从数字签名模式中拿出一个公共验证密钥,并将其与一个人或一个系统参与者的身份对等。如果你见到一条消息的签名被公钥 pk 正确验证,那么你可以认为 pk 就是在表达这条消息。你真的可以将公钥认为是参与者或者系统的一方,他可以通过签署声明而发布声明。从这个角度来说,公钥就是身份,让某人能为 pk 身份发声,他必须知道相应的密钥 sk 。 将公钥视为身份的一个结果是,你可以随时制定新的身份——你可以简单通过数字签名方案中的 generateKeys 程序,生成新的密钥对 sk pk pk 是你可以使用的新的公共身份, sk 是相应的密钥,只有你自己知道并可以让你代表身份为 pk 发声。在实践中,你可能会使用 pk 的哈希作为你的身份,这是因为公钥很大。如果是这样的话,为了验证消息来自你的身份,人们会需要验证:

  • (1)你的身份确实是 pk 的哈希;
  • (2)信息能经过公钥 pk 验证。

此外,在默认情况下,你的公钥 pk 基本上看起来是随机的,也并没有人能够通过检查 pk 发现你的现实身份(当然,一旦你开始使用这个身份发表声明,这些声明可能泄露信息,而让别人将你的真实身份与 pk 联系起来。我们很快会更详细地讨论这个问题)。你可以生成一个看起来随机的新身份,看起来像人群中的一张脸,但这些都只有你能够控制。

编程要求

根据提示,在右侧编辑器补充代码,根据公钥即身份,我们可以模拟一次消息签名,假如你的身份是 e ,有哈希函数 H(x)=ax+b ,那么我们可以把 pk=H(e) 作为公钥, sk=H(e)−1modq 作为私钥,我们用私钥对消息m进行加密,即 en(m)=sk∗m ,那么我们解密就可以这样计算 de(en(m))=en(m)∗pk 。这里 q 保证是素数。 输入

 e a b q m

输出

 pk sk en(m)

输入

 3 4 5 11 6

输出

17212

提示: 费马定理求逆元,可以查询一下。

代码

ksm求逆元

b 与 p 互质情况下,若 a/b ≡ a*x (mod p),则 x 为 b 的 乘法逆元

可转化为 b * x ≡ 1 (mod p)

费马定理 :若 p 为质数,得:b p-1 ≡ 1 (mod p)

又有:b * x ≡ 1 (mod p)

得到:b * b p-2 ≡ 1 (mod p),所以 x = b p-2

// 题目规定 p 是质数,我们使用费马定理需要 a p 是互质并且 p 是质数
// 只有 a 是 p 得倍数时,不互质

if (a % p == 0) System.out.println("impossible");
else System.out.println(quick_power(a, p - 2, p));

// 快速幂
private static long quick_power(long a, long k, long p) {
    long ans = 1;
    while (k > 0) {
        if ((k & 1) == 1) ans = ans * a % p;
        k >>= 1;
        a = a * a % p;
    }
    return ans;
}
#include<bits/stdc++.h>
using namespace std;
int e,a,b,q,m;

// 快速幂求逆元
long ksm(long a, long k, long p) {
    long ans = 1;
    while (k > 0) {
        if ((k & 1) == 1) ans = ans * a % p;
        k >>= 1;
        a = a * a % p;
    }
    return ans;
}

// 哈希函数
int H(int x) {
    return a * x + b;
}

// 公钥
int pk() {
    return H(e);
}

// 私钥
int sk() {
    return ksm(H(e), q-2, q);
}

// 加密
int en() {
    return sk() * m;
}

int main()
{
    cin>>e>>a>>b>>q>>m;
    cout << pk() << endl;
    cout << sk() << endl;
    cout << en() << endl;
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

头歌—密码学基础 的相关文章

随机推荐

  • activemq启动成功但web管理页面却无法访问

    前提 在linux启动activemq成功 本地能ping通linux 处理方案 确定防火墙是否关闭 有两种处理方案 第一种 关闭防火墙 第二种 暴漏8161和61616两个端口 netstat lnpt 查看8161和61616端口 注意
  • 时间序列数据压缩算法简述

    本文简单介绍了时间序列压缩任务的来源 压缩算法的分类 并对常见压缩算法的优缺点进行了简介 爱码士们快来一探究竟呀 引言 时间序列数据是在许多应用程序和领域中生成的一种基本数据类型 例如金融 医疗保健 交通和智慧城市 1 时间序列分析对于各种
  • Docker容器状态显示

    个人笔记 努力奋斗 文章目录 docker ps docker stats 总结 docker ps Docker中 你可以使用以下命令来查看容器的状态 docker ps 这个命令用于列出正在运行的容器 默认情况下 它只显示正在运行的容器
  • 企业ERP软件定制开发对企业的优势|app小程序搭建

    企业ERP软件定制开发对企业的优势 app小程序搭建 ERP Enterprise Resource Planning 软件定制开发是根据企业的具体需求和业务流程特点 定制开发的一种软件解决方案 相比于通用的ERP软件 定制开发可以更好地满
  • 常用的jQuery事件有几种?

    jQuery提供了多种事件处理方法 常用的jQuery事件包括以下几种 click事件 当元素被点击时触发 button click function 点击事件处理逻辑 hover事件 当鼠标悬停在元素上时触发 div hover func
  • 算法与数据结构(二十五)TopK问题:基于快排的Python模板

    首先 先写partition模板 def partition nums left right pivot nums left 初始化一个待比较数据 i j left right while i lt j while i
  • easyrecovery2024绿色版中文语言电脑数据恢复工具

    平时很多人都会把自己工作时 或者生活中的数据存储在我们的电脑上 很多时候 由于我们的误操作或者是其它某些问题 很容易就会误删除一些文件数据了 尤其是一些电脑出现故障 总是会导致数据丢失 这让人非常烦恼 需要重装系统的时候 往往一些文件就无法
  • 2、Linux_远程操作

    远程操作 1 配置ifconfig 1 1输入 ifconfig 查看 ip 的命令 ifconfig 1 2搜索 ifconfig 命令 yum search ifconfig 1 3配置网卡 进入如下目录配置网卡 cd etc sysc
  • 2024不收费的数据恢复软件EasyRecovery16

    EasyRecovery2024是一款操作安全 用户可自主操作的数据恢复方案 它支持从各种各样的存储介质恢复删除或者丢失的文件 其支持的媒体介质包括 硬盘驱动器 光驱 闪存 硬盘 光盘 U盘 移动硬盘 数码相机 手机以及其它多媒体移动设备
  • matplotlib多子图

    matplotlib画图中一个轴占据多个子图 知乎 import matplotlib pyplot as plt fig plt figure gs fig add gridspec 2 4 ax1 fig add subplot gs
  • 目标检测算法改进系列之添加变核卷积AKConv模块

    AKConv变核卷积 KConv的主要思想 AKConv 可变核卷积 主要提供一种灵活的卷积机制 允许卷积核具有任意数量的参数和采样形状 这种方法突破了传统卷积局限于固定局部窗口和固定采样形状的限制 从而使得卷积操作能够更加精准地适应不同数
  • 【LeetCode:1038. 从二叉搜索树到更大和树 | BST+DFS+中序遍历】

    算法题 算法刷题专栏 面试必备算法 面试高频算法 越难的东西 越要努力坚持 因为它具有很高的价值 算法就是这样 作者简介 硕风和炜 CSDN Java领域新星创作者 保研 国家奖学金 高中学习JAVA 大学完善JAVA开发技术栈 面试刷题
  • 【日常踩坑】Debug 从入门到入土

    文章目录 分类 事后 addr2line objdump 反汇编 计算偏移量 优化
  • [原创]C++98升级到C++20的复习旅途-从汇编及逆向角度去分析“constexpr“关键字

    简介 常用网名 猪头三 出生日期 1981 XX XX QQ 643439947 个人网站 80x86汇编小站 https www x86asm org 编程生涯 2001年 至今 共22年 职业生涯 20年 开发语言 C C 80x86A
  • 为什么阿里巴巴修正了HashMap关于1024个元素扩容的次数?

    来源 juejin cn post 7302724955699789863 引言 第一次put调用resize 调用resize 的次数 总结 引言 最近在翻看 阿里巴巴开发手册 嵩山版 即最新版时 发现其修正了关于 HashMap关于10
  • 关于svn如何上传一个完整的项目

    注意 请一定要按照该步骤进行操作 请上传新项目时将项目名称进行规范命名 例如原始文件是arrange v2 将此项目需要注入新的医院 则命名为 arrange 某医院名称 门诊或者医技或者药房 v2 重新命名文件夹名称快捷键 F12 一 先
  • 目标检测算法改进系列之添加SCConv空间和通道重构卷积

    SCConv 空间和通道重构卷积 SCConv 空间和通道重构卷积 的高效卷积模块 以减少卷积神经网络 CNN 中的空间和通道冗余 SCConv旨在通过优化特征提取过程 减少计算资源消耗并提高网络性能 该模块包括两个单元 1 空间重构单元
  • 自动化测试的4大注意事项

    自动化测试能够提高测试效率 覆盖率 降低测试成本和工作量 是软件开发中不可或缺的一部分 但前提是要确保自动化测试的有效性和可靠性 否则无效或错误的自动化测试 往往会对项目造成负面影响 如维护成本高 假阳性和假阴性等问题 因此我们在进行自动化
  • 给出employees表中排名为奇数行的first_name

    给出employees表中排名为奇数行的first name select e first name first from employees e join select first name row number o 题解 二叉树中和为某
  • 头歌—密码学基础

    第1关 哈希函数 题目 任务描述 本关任务 利用哈希算法统计每个字符串出现的个数 相关知识 为了完成本关任务 你需要掌握 1 密码学哈希函数的概念及特性 2 安全哈希算法 密码学哈希函数的概念及特性 我们需要理解的第一个密码学的基础知识是密