curses-键盘编码-openssl加解密【转】

本文转载自;https://zhuanlan.zhihu.com/p/26164115

1.1 键盘编码

按键过程:
当用户按下某个键时,

1.键盘会检测到这个动作,并通过键盘控制器把扫描码(scan code)传送到计算机;键盘扫描码跟具体的硬件有关的,不同厂商对同一个键的扫描码有可能不同。
2.计算机接收到扫描码后,将其交给键盘驱动程序;
3.键盘驱动程序把这个扫描码转换为键盘虚拟码;虚拟码与具体硬件无关,不同厂商的键盘,同一个键的虚拟码总是相同的。然后,键盘驱动程序把该键盘操作的扫描码和虚拟码以及其它信息传递给操作系统;
4.操作系统将获得的信息封装在一个键盘消息中,并把该键盘消息插入到消息列队。
5.通过Windows的消息系统,该键盘消息被送到某个窗口中;
6.窗口所在的应用程序接收到消息后,可以了解到有关键盘操作的信息,然后决定作出一定的响应。

在Linux下,可以通过自带的showkey来获取:

showkey --help
showkey 版本 1.15.5
用法: showkey [选项...]
有效的选项:
    -h --help   显示此帮助文本
    -a --ascii  显示键的十进制/八进制/十六进制值
    -s --scancodes  只显示原始扫描码
    -k --keycodes   只显示翻译后的键码(默认)

KeyCode参数是指的键代码,也就是虚拟码。它用来在系统中标识一个键,注意,仅仅用于在系统中标识。我们通常不是直接用这个代码(数字,直接用还是很不好记忆),而是将它定义为字符常量,比如在curses库里,可以发现对每个键的相应定义,#define KEY_DOWN 0402。需要说明的是,每个键的虚拟码都是唯一的,也就是不区分大小写,只用来表示一个位置,而不表示键的状态。
KeyAscii参数就比较容易理解了,当然就是键的ascii码,强调表示一个字符,而不是强调键。某些按键,比如方向键,是因为这些键没有传统意义上的Ascii码(这些键只有虚拟码),所以需要用多个ascii码组合,比如F2: ^[OQ
scancodes是指扫描码,

键盘上的每一个键都有两个唯一的数值进行标志。为什么要用两个数值而不是一个数值呢?这是因为一个键可以被按下,也可以被释放。当一个键按下时,它们产生一个唯一的数值,当一个键被释放时,它也会产生一个唯一的数值,我们把这些数值都保存在一张表里面,到时候通过查表就可以知道是哪一个键被敲击,并且可以知道是它是被按下还是被释放了。这些数值在系统中被称为键盘扫描码。

1.2 加密解密

1.2.1 单向加密

只能加密,不能解密,不可逆。常见的有:MD5(Message Digest algorithm 5,信息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)、HMAC(Hash Message Authentication Code,散列消息鉴别码)。

1.2.2 对称加密

对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥和解密密钥是相同的,或者加密/解密密钥能够从解密/加密密钥中推算出来,所以也称这种加密算法为秘密密钥算法或单密钥算法。
常见的有DES、AES、RC系列算法。

1.2.3 非对称加密

非对称加密算法(asymmetric cryptographic algorithm)又名“公开密钥加密算法”。常见:RSA、DSA等算法。

2.实验

本次实验我主要借助linux自带的showkey工具实现了键盘编码的输出,利用openssl库实现了md5、sha1、rsa加密解密。使用curses库做了菜单。

2.1 键盘编码

showkey是linux keyboard 工具集合中的一个,代码开源,,可以看出它主要是通过和键盘设备进行交互,获取键的编码值。
ascii编码,

扫描码,可以看到是两个编码,按下和释放两种状态。

2.2 加密解密

2.2.1 md5和SHA加密

实际上,他们都不算是真正的加密算法,更准确的是一种哈希算法,通过散列算法,变换成固定长度的输出,是一种压缩映射,散列值的空间通常远小于输入的空间。 简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。


SHA1和MD5的算法都是从MD4算法改进而来的2种算法,基本思路都是将信息分成N个分组,每组64个字节,每个分组都进行摘要运算。当一个分组的摘要运算完毕后,将上一个分组的结果也用于下一个分组的运算。

2.2.2 rsa 非对称加密算法

1976年以前,所有的加密方法都是同一种模式:
(1)甲方选择某一种加密规则,对信息进行加密;
(2)乙方使用同一种规则,对信息进行解密。
由于加密和解密使用同样规则(简称”密钥”),这被称为”对称加密算法”(Symmetric-key algorithm)。
这种加密模式有一个最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。
而”非对称加密算法”。
(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。
如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
本次实验我利用openssl这个库里的rsa函数进行了加密解密。主要步骤如下:
生成一个密钥(包含公钥和私钥),然后将公钥提取出来

openssl genrsa -out test.key 1024
openssl rsa -in test.key -pubout -out test_pub.key

就可以利用生成的密钥进行加密解密了。

几个关键词

密钥流:RC4算法的关键是根据明文和密钥生成相应的密钥流,密钥流的长度和明文的长度是对应的,也就是说明文的长度是500字节,那么密钥流也是500字节。当然,加密生成的密文也是500字节,因为密文第i字节=明文第i字节^密钥流第i字节;
状态向量S:长度为256,S[0],S[1]…..S[255]。每个单元都是一个字节,算法运行的任何时候,S都包括0-255的8比特数的排列组合,只不过值的位置发生了变换;
临时向量T:长度也为256,每个单元也是一个字节。如果密钥的长度是256字节,就直接把密钥的值赋给T,否则,轮转地将密钥的每个字节赋给T;
密钥K:长度为1-256字节,注意密钥的长度keylen与明文长度、密钥流的长度没有必然关系,通常密钥的长度取为16字节(128比特)。

RC4的原理分为三步
1. 初始化S和T

for i=0 to 255 do
   S[i]=i;
   T[i]=K[ i mod keylen ];
  1. 初始排列S
j=0;
for i=0 to 255 do
   j= ( j+S[i]+T[i])mod256;
   swap(S[i],S[j]);
  1. 产生密钥流
i,j=0;
for r=0 to len do  //r为明文长度,r字节
   i=(i+1) mod 256;
   j=(j+S[i])mod 256;
   swap(S[i],S[j]);
   t=(S[i]+S[j])mod 256;
   k[r]=S[t];//K为密钥

利用密钥流与明文进行按位异或。

3.实验总结

经过本次实验,了解了键盘编码的过程和方式,熟悉了curses 终端gui编程,掌握了openssl库进行常用的加解密算法,同时也强化了树莓派的使用。

4.遇到的问题

    1. curses不支持中文
      字符集的设置,源代码中要#include <locale.h>,同时在main函数中setlocale(LC_ALL,"");
      编译时要选择宽字符集版本gcc -o hello hello.c –lncursesw 而不是gcc -o hello hello.c –lcurses(可以通过apt-get install libncursesw5安装)
    2. curses库里的键盘编码是curses自定义的一套编码,与虚拟键码有区别。一开始混淆了这个。
    3. curses菜单编程比较生疏,二级菜单没有实现,也没有实现标题栏式的菜单。
原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7340680.html