加密与认证

任务 采用Java/Python语言编写一个较为完整的加密与认证程序,要求具有: 具有较完整的图形化界面; 使用MD5、SHA系列算法,实现消息摘要,确保消息的完整性; 使用DES、AES等算法实现对称加密,确保消息的机密性; 使用RSA算法,实现公钥加密,且用私钥解密,比较不对称加密和对称加密的性能; 实现基于数字证书的数字签名和验证(含证书的生成和创建); 消息摘要 消息摘要的作用 在网络安全目标中,要求信息在生成、存储或传输过程中保证不被偶然或蓄意地删除、修改、伪造、乱序、重放、插入等破坏和丢失,因此需要一个较为安全的标准和算法,以保证数据的完整性。 常见的消息摘要算法有: Ron Rivest设计的MD(Standard For Message Digest,消息摘要标准)算法 NIST设计的SHA(Secure Hash Algorithm,安全散列算法) 单向散列函数 特点 不定长的输入和定长的输出; 对于及其微小的变化,如1bit的变化,器哈希函数所产生的值也差异巨大; 对于不同的原像都有不同的映像,从散列值不可能推导出消息M ,也很难通过伪造消息M’来生成相同的散列值。 Hash函数的值称为作为自变量的消息的“散列值”或“消息摘要”、“数字指纹” 哈希函数的分类 根据安全水平 弱无碰撞 强无碰撞 ​ 注:强无碰撞自然含弱无碰撞! 根据是否使用密钥 带秘密密钥的Hash函数:消息的散列值由只有通信双方知道的秘密密钥K来控制,此时散列值称作MAC(Message Authentication Code) 不带秘密密钥的Hash函数:消息的散列值的产生无需使用密钥,此时散列值称作MDC(Message Detection Code) 哈希函数的应用 由Hash函数产生消息的散列值 以消息的散列值来判别消息的完整性 用加密消息的散列值来产生数字签名 用口令的散列值来安全存储口令(认证系统中的口令列表中仅存储口令的Hash函数值,以避免口令被窃取。认证时用输入口令的Hash函数值与其比较) 安全哈希函数的实现 输入数据分成L个长度固定为r的分组:M=(M1,M2,…,ML) 末组附加消息的长度值并通过填充凑足r位 压缩函数 f使用n位的链接变量Hi ,其初值H0=IV可任意指定 压缩函数 f的最后n位输出HL取作散列值 哈希函数:生日攻击 当哈希函数的输入位数太短的时候,就容易产生哈希碰撞,即出现两个原像对应用一个映像的问题。 生日问题 一个教室中至少有几个学生才能使有两个学生生日相同的概率不小于1/2; 等价于“球匣问题” 设J个球随机扔进N个匣子,存在一个匣子中至少有两个球的概率为p,则可以推导出: J2≈-2Nln(1-p)或 p≈ 1-e-J2/2/N 答案 将365个生日看作N=365个匣子,将学生看作球,p=0.5,则由上式可算出J≈23,即23个学生中有两个学生生日相同的概率不小于1/2; 生日攻击实例: ​ 假设张三承诺支付李四100万,约定由李四负责起草合同,并通过8位的散列码H(M)实施信息认证。聪明而无德的李四先起草一个100万的版本,并通过变化其中3个无关紧要之处以得到23=8个不同的消息明文并计算它们的H(M),形成集合A;然后再起草一个200万的版本,用同样方法又得到23=8 个不同的消息明文及其H(M),形成集合B。 ​ 由生日问题知:24个8位比特串中发生碰撞的概率不小于1/2,故在A和B共24 =16个H(M)中有可能存在相同的一对,并极有可能一个在A中而另一个在B中。假设与它们对应的明文为MA (100万版) 和MB (200万版) 。于是李四用MA让张三签署并公证,而在传送时偷偷地用MB替代MA 。由于H(MA)= H(MB),故张三确信签署的文件未被篡改。当李四要求张三支付200万时,法院根据MB判李四胜诉,而张三因此损失100万。...

April 12, 2023 · 4 min · 713 words · sirius1y

k8s学习和实践:腾讯云轻量级服务器上搭建网站

Service类型 在 Kubernetes 中,Service 是一种抽象的概念,用于将一组 Pod 组织在一起,并为它们提供统一的访问入口。Service 可以通过一组稳定的 IP 地址和端口号,为其他容器或外部用户提供对这些 Pod 的访问。 为什么需要服务? pod的存在是短暂的,当pod因为节点故障或者人为原因下线的时候,ReplicationController可以上线一个新的pod。但是新的pod和原来的pod的IP是不相同的——为了解决不断变化的pod IP地址的问题,以及在一个固定的IP和端口对外暴露多个pod。 当一个服务被创建时,他会得到一个静态的IP,在服务的生命周期中这个IP不会发生变化。客户端应该通过这个固定IP地址连接到服务,而不是直接连接到pod。 服务的类型 Kubernetes 中的 Service 有以下四种类型: 1、ClusterIP 这是默认的 Service 类型,用于将 Service 暴露在集群内部。它为每个 Service 分配一个虚拟 IP 地址,可以通过该地址访问 Service 中的 Pod。ClusterIP 只能从集群内部访问,不能从集群外部访问。 2、NodePort 这种类型的 Service 将 Service 暴露到集群外部,通过将每个节点上的端口映射到 Service 上,可以让外部用户通过任意节点的 IP 地址和映射端口访问 Service 中的 Pod。NodePort 通常用于测试和开发环境,不太适合生产环境。 3、LoadBalancer 这种类型的 Service 可以将 Service 暴露到集群外部,并使用云提供商的负载均衡器将流量路由到 Service 中的 Pod。LoadBalancer 只能在云提供商支持的环境中使用,并且需要正确配置云提供商的负载均衡器才能正常工作。 4、ExternalName 这种类型的 Service 可以将 Service 暴露到集群外部,但它并不会创建任何代理或负载均衡器,而只是将 Service 映射到一个 DNS 名称。这可以让您在 Kubernetes 中使用外部服务,或者在不同的命名空间中重用服务。...

October 30, 2022 · 6 min · 1193 words · sirius1y

数据结构学习笔记

一、绪论 数据(data)是信息的载体,是描述客观事物的数、字符、图形、图像、声音以及所有能输入计算机中并被计算机程序识别和处理的符号的集合。 数据的最小单位的是数据项; 数据的基本单位是数据元素,一个数据元素可由若干个数据项组成。 数据结构分为两大类:线性结构和非线性结构 两类结构通常分为四类基本结构: 1)集合:结构中的数据元素之间同属于一个集合,此外没有其他关系; 2)线性结构:结构中的数据元素之间存在一种线性关系,一对一的关系; 3)树形结构:一对多的关系; 4)图形结构或网状结构:多对多的关系。 根据视点的不同又可分为:逻辑结构和物理结构: 逻辑结构:面向问题,描述数据元素之间的逻辑关系; 物理结构:又称存储结构,面向计算机,是数据结构在计算机中的表示(映像) 算法的特性:输入性、输出性、确定性、有穷性、有效性(可行性) 算法的标准:正确性(满足所要求界的问题的需求,最重要最基本)、可用性(便于用户使用,良好的界面、完备的用户文档)、可读性(易于理解)、效率(存储单元的开销和运行时间的耗费)、健壮性(对于非法数据的处理) 算法复杂度:(渐进)时间复杂度和空间复杂度 二、线性结构 1、线性表 1.1 顺序表示:顺序表 用顺序结构存储的线性表为顺序表(sequential list)。 顺序表一般用数组进行存储 类模板定义:T* elems,int length,int maxLength 1.2 链表表示 1) 单链表 分为带头结点和不带头结点的单链表; 带头结点的单链表相对不带头结点的单链表在涉及会更改头节点的任务时,操作会更加统一。 类模板定义: (结点)T data,Node* next (单链表)Node* head,int length 2) 双向循环链表 类模板定义: (结点)T data,Node* prior,Node* next (双向循环链表)Node* head,int length *带头结点的双向循环列表只有一个元素结点的条件:head->next!=head && head->next->next==head 3) 静态链表 利用数组来模拟存储空间实现链表。 类模板定义: (结点)T data,Node* next (静态链表)Node* head,Node* avail 设数组a放置了一个静态链表,当链表未使用的时候,其中所有的结点都是形成了一个链表,用avail进行管理,代表未使用的结点。 当进行插入操作的时候,就从avail中取出一个头节点,进行赋值,再放入head链表之中。 在完成每一步操作之后,记得要将next域中更改 插入元素操作: i=avail; avail=a[avail].next; a[i].next=a[head],next; a[head]。next=i; 当需要释放由j所指向的结点时,只需要把结点j放到avail表的最前端,并让avail指向它即可。...

October 26, 2022 · 19 min · 3943 words · sirius1y

CPP学习笔记

C++学习笔记 现在主流的编译型语言包括C、C++、Go、Rust等,它们的编译过程中需要将代码转换成机器语言,因此可以获得更高的执行效率和更好的性能。 而主流的解释型语言包括Python、Ruby、JavaScript等,这些语言需要解释器将代码转换成机器语言并运行,因此相对于编译型语言,它们的执行效率和性能可能会稍低,但是它们通常具有更高的开发效率和更强的灵活性,因为它们可以在运行时动态修改代码。 另外,还有一些语言是即时编译型语言(JIT),例如Java、C#和LuaJIT等,这些语言的编译器会在运行时将代码编译成机器语言,因此它们的执行效率和性能通常比解释型语言要高一些,但比编译型语言略低一些。 函数的声明和定义中, 不能重复定义一个参数的值; 带有默认值的形式参数必须放在参数列表的最右侧; 一、cin 函数的用法 使用cin从标准输入读取数据时,通常用到的方法有cin»,cin.get,cin.getline。 1.1 cin»的用法 (1)cin»等价于cin.operator»(),即调用成员函数operator»()进行读取数据。 (2)当cin»从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin»会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin»不做处理。 (3)不想略过空白字符,那就使用 noskipws 流控制。比如cin»noskipws»input; 1.2 cin.get的用法 1.2.1 cin.get读取一个字符 读取一个字符,可以使用cin.get或者cin.get(var),示例代码如下: #include <iostream> using namespace std; int main() { char a; char b; a=cin.get(); cin.get(b); cout<<a<<b<<endl; system("pause"); return 0; } 输入:e[回车],输出: 注意: (1)从结果可以看出,cin.get()从输入缓冲区读取单个字符时不忽略分隔符,直接将其读取,就出现了如上情况,将换行符读入变量b,输出时打印两次。 (2)cin.get()的返回值是int类型,成功:读取字符的ASCII码值,遇到文件结束符时,返回EOF,即-1,Windows下标准输入输入文件结束符为Ctrl+z,Linux为Ctrl+d。cin.get(char var)如果成功返回的是cin对象,因此可以支持链式操作,如cin.get(b).get(c)。 1.2.2 cin.get读取一行 读取一行可以使用istream& get ( char* s, streamsize n )或者istream& get ( char* s, size_t n, streamsize delim )。二者的区别是前者默认以换行符结束,后者可指定结束符。n表示目标空间的大小。示例代码如下: #include <iostream> using namespace std; int main() { char a; char array[20]={NULL}; cin....

March 19, 2022 · 7 min · 1375 words · sirius1y

牛客华为题库刷题记录 HJ1 字符串最后一个单词的长度 处理字符串输入使用了 bufio.NewScanner(os.Stdin) ,然后再循环 .Scan() 方法读取 思路:读入字符串,使用 strings.Split(字符串,分隔符)进行拆分为数组,然后读取最后一个数组的长度 package main import ( "bufio" "fmt" "os" "strings" ) func main() { input := bufio.NewScanner(os.Stdin) for input.Scan(){ arr:=strings.Split(input.Text(), " ") fmt.Println(len(arr[len(arr)-1])) } } HJ2 计算某字符出现次数 这里涉及到了两行的读取,使用 bufio.NewScanner(os.Stdin) 进行读取 bufio.NewScanner 是一行一行的读取;fmt.Scan 是读取的时候遇到空格就停 计算某个字符出现的次数,使用strings.count(字符串, 要统计的字符) package main import ( "bufio" "fmt" "os" "strings" ) func main() { scanner := bufio.NewScanner(os.Stdin) scanner.Scan() a_string := scanner.Text() scanner.Scan() target := scanner.Text() a_string=strings.ToLower(a_string) target=strings.ToLower(target) count:=strings.Count(a_string, target) fmt....

4 min · 773 words · sirius1y