OpenEuler基础实验

20191331 lyx

基于 鲲鹏--OpenEuelr 20.03 64bit--ARM (华为云服务器)

实验环境:鲲鹏--OpenEuelr 20.03 64bit--ARM

OpenEuler基础实验_#include

使用Xshell连接

OpenEuler基础实验_汇编语言_02

PS:Xshell是一款非常好用的远程连接工具,其自带的文件管理系统可以非常直观的进行文件管理,是符合我们平时Windows系统交互逻辑的,可以非常快捷的进行双向文件传输。

OpenEuler基础实验_文件句柄_03

基于openEuler的OpenSSL编译安装和编程实践

  • 检查openssl版本

OpenEuler基础实验_#include_04

当前openEuler系统安装的OpenSSL版本是1.1.1d,现在(2021.04)OpenSSL最新的版本是1.1.1l.

  • openEuler中没有变成开发需要的头文件。我们需要自己下载OpenSSL的源码编译安装。

1.首先去OpenSSL官网下载最新版OpenSSL源码。

OpenEuler基础实验_汇编语言_05

链接:​​https://www.openssl.org/source/​

2.新建两个文件夹,分别放置OpenSSL的源码和安装路径。

[root@arm ~]# mkdir lyx-opensslsrc lyx-openssl
[root@arm ~]# cd lyx-openssl
[root@arm lyx-openssl]# pwd
/root/lyx-openssl


OpenEuler基础实验_linux_06

3.将源码上传并解压至lyx-opensslsrc文件夹:

tar -zxvf openssl-1.1.1l.tar.gz -C ./


OpenEuler基础实验_linux_07

4.配置编译安装路径(/root/lyx-openssl),和openEuler系统默认的不同。

cd rocopensslsrc/openssl-1.1.1k
./config --prefix=/root/rocopenssl


OpenEuler基础实验_汇编语言_08

5.编译(make时间稍长,耐心等待),测试、安装,其中测试步骤可选:

make
make test
make install


6.查看安装后的版本,确定是最新安装的1.1.1l版:

cd ~/rocopenssl
./bin/openssl version


安装成功:

OpenEuler基础实验_数据_09

OpenSSL命令的使用

通过 ​​openssl help​​ 查看帮助文档:

OpenEuler基础实验_#include_10

OpenSSL编程

密码算法库的功能非常强大,是OpenSSL的基础,它实现了现代密码学大部分主流的密码算法和标准,主要包括公开密钥(非对称)算法、对称加密算法、信息摘要算法、X509 数字证书标准、PKCS12个人信息交换语法标准、PKCS7 加密消息语法标准、OCSP 在线证书状态查询协议、 CRL 证书吊销列表等标准。同时 OpenSSL 还提供了Engine 机制;利用 Engine 可以将加密卡、加密机这样的外部硬件算法模块无缝集成到 OpenSSL 中。

什么是SSL

  • 为了让网络通信更安全,需要认证和加密,认证是说明你是要找的人,加密是为了让截获中间报文第三者无法得到消息内容。
  • 为此有人设计了SSL,即套接字上的安全层,简单来说就是在TCP之上做一个安全通信层,HTTP on SSL 即是HTTPs,现在几乎所有的银行网站访问都是基于HTTPS协议的。
  • 认证是通过证书+非对称加密算法来解决的

于是便有了OpenSSL

  • SSL交互过程还是很复杂的,牵扯到非对称加密和对称加密,以及复杂的交互过程,为此有人写了openssl库,这个库的使用非常广泛,本文就是阐明如何安装和基本使用这个库的。
  • 有了这openssl库,就可以直接写和HTTPS的交互的代码了。

OpenSSL功能

openssl可以实现:秘钥证书管理、对称加密和非对称加密 。

openssl: 多用途的命令行工具,包openssl,可以执行交互或批量命令。
libcrypto: 加密算法库,包openssl-libs。
libssl:加密模块应用库,实现了ssl及tls,包nss。


  • 作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。

一个简单测试

#include <stdio.h>
#include <openssl/evp.h>

int main(){

OpenSSL_add_all_algorithms();

return 0;
}


编译:

​gcc -o to test_openssl.c -I /root/lyx-openssl/include -L /root/lyx-openssl/lib -lcrypto -lpthread​

OpenEuler基础实验_linux_11

执行 ​​./to;echo $?​​:

OpenEuler基础实验_汇编语言_12

BASE64算法

编写一个BASE64的测试代码 ​​testbase64.c​​:

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>

//Base64编码
void tEVP_Encode()
{
EVP_ENCODE_CTX *ctx;
ctx = EVP_ENCODE_CTX_new(); //EVP编码结构体
unsigned char in[1024]; //输入数据缓冲区
int inl; //输入数据长度
char out[2048]={0}; //输出数据缓冲区
int outl; //输出数据长度
FILE *infp; //输入文件句柄
FILE *outfp; //输出文件句柄

infp = fopen("test.dat","rb");//打开待编码的文件
if(infp == NULL)
{
printf("Open File \"Test.dat\" for Read Err.\n");
return;
}

outfp = fopen("test.txt","w");//打开编码后保存的文件
if(outfp == NULL)
{
printf("Open File \"test.txt\" For Write Err.\n");
return;
}
EVP_EncodeInit(ctx);//Base64编码初始化
printf("文件\"Test.dat\" Base64编码后为:\n");
//循环读取原文,并调用EVP_EncodeUpdate计算Base64编码
while(1)
{
inl = fread(in,1,1024,infp);
if(inl <= 0)
break;
EVP_EncodeUpdate(ctx,out,&outl,in,inl);//编码
fwrite(out,1,outl,outfp);//输出编码结果到文件
printf("%s",out);
}
EVP_EncodeFinal(ctx,out,&outl);//完成编码,输出最后的数据。
fwrite(out,1,outl,outfp);
printf("%s",out);
fclose(infp);
fclose(outfp);
printf("对文件\"Test.dat\" Base64编码完成,保存到\"test.txt\"文件.\n\n\n");
}

//Base64解码
void tEVP_Decode()
{
EVP_ENCODE_CTX *ctx;
ctx = EVP_ENCODE_CTX_new(); //EVP编码结构体
char in[1024]; //输入数据缓冲区
int inl; //输入数据长度
unsigned char out[1024]; //输出数据缓冲区
int outl; //输出数据长度
FILE *infp; //输入文件句柄
FILE *outfp; //输出文件句柄

infp = fopen("test.txt","r");//打开待解码的文件
if(infp == NULL)
{
printf("Open File \"Test.txt\" for Read Err.\n");
return;
}
outfp = fopen("test-1.dat","wb");//打开解码后保存的文件
if(outfp == NULL)
{
printf("Open File \"test-1.txt\" For Write Err.\n");
return;
}
EVP_DecodeInit(ctx);//Base64解码初始化
printf("开始对文件\"Test.txt\" Base64解码...\n\n");
//循环读取原文,并调用EVP_DecodeUpdate进行Base64解码
while(1)
{
inl = fread(in,1,1024,infp);
if(inl <= 0)
break;
EVP_DecodeUpdate(ctx,out,&outl,in,inl);//Base64解码
fwrite(out,1,outl,outfp);//输出到文件
}
EVP_DecodeFinal(ctx,out,&outl);//完成解码,输出最后的数据。
fwrite(out,1,outl,outfp);
fclose(infp);
fclose(outfp);
printf("对文件\"Test.txt\" Base64解码完成,保存为\"test-1.dat\"\n\n\n");

}

int main()
{

tEVP_Encode();
tEVP_Decode();

return 0;
}


通过​​gcc -o testbase64 testbase64.c -I /root/lyx-openssl/include -L /root/lyx-openssl/lib -lcrypto -lpthread -finput-charset=GBK -fexec-charset=UTF-8​​编译:

出现错误:

OpenEuler基础实验_#include_13

原因是缺少中文字体库

OpenEuler基础实验_数据_14

安装必要的字体库:

​yum groupinstall -y fonts​

OpenEuler基础实验_数据_15

再次编译,成功:

OpenEuler基础实验_汇编语言_16

执行 ​​./testbase64​​ :

OpenEuler基础实验_汇编语言_17

test.dat 是一个二进制文件 内容为:​​20191331 lyx hello BASE64​

汇编语言练习

3.2汇编语言练习——查找最大数

  • 1.实验目的

通过本实验了解和熟悉 ARM64 汇编语言。

  • 2.实验要求
  • 使用 ARM64 汇编语言来实现如下功能:在给定的一组数中查找最大数。
  • 程序可使用GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实验平台上运行。
.section .data
.align 3
my_data:
.quad 1
.quad 2
.quad 5
.quad 8
.quad 10
.quad 12

my_data_count:
.quad 6

.align 3
print_data:
.string "big data: %d\n"

.section .text
.globl main
main:
stp x29, x30, [sp, -16]!

ldr x0, =my_data
ldr x1, my_data_count

add x4, x0, #40

mov x3, xzr
1:
ldr x2, [x0], #8
cmp x2, x3
csel x3, x2, x3, hi

cmp x0, x4
b.ls 1b

ldr x0, =print_data
mov x1, x3

bl printf

ldp x29, x30, [sp], 16
ret


编译运行:

OpenEuler基础实验_数据_18

编译时犯了个错:忘记汇编代码后缀为 ​​.s​

调试:

OpenEuler基础实验_#include_19

3.3汇编语言练习——通过 C 语言调用汇编函数

  • 1.实验目的

通过本实验了解和熟悉 C 语言中如何调用汇编函数。

  • 2.实验要求
  • 使用 ARM64 汇编语言来实现如下功能:在给定的一组数中查找最大数。
  • 程序可使用GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实验平台上运行。
*****************compare.S******************
.section .text
.globl compare_data
compare_data:
cmp x0, x1
csel x0, x0, x1, hi
ret
*******************main.c********************
#include <stdio.h>
extern int compare_data(int a, int b);
int main()
{
int val;
val = compare_data(5, 6);
printf("big data: %d\n", val);
}


编译运行:

OpenEuler基础实验_linux_20

3.4汇编语言练习——通过汇编语言调用 C 函数

  • 1.实验目的

通过本实验了解和熟悉 C 语言中如何调用汇编函数。

  • 2.实验要求
  • 使用 ARM64 汇编语言来实现如下功能:在给定的一组数中查找最大数。
  • 程序可使用GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实验平台上运行。
*************compare.c************
int compare_data(int a, int b)
{
return (a >= b) ? a : b;
}
***************main.s**************
.section .data
.align 3
print_data:
.string "big data: %d\n"
.section .text
.globl main
main:
stp x29, x30, [sp, -16]!
mov x0, #6
mov x1, #5
bl compare_data
mov x1, x0
ldr x0, =print_data
bl printf
ldp x29, x30, [sp], 16
ret


编译运行:

OpenEuler基础实验_#include_21

3.5汇编语言练习——GCC 内联汇编

#include <stdio.h>
static int compare_data(int a, int b)
{
int val;
asm volatile (
"cmp %1, %2\n"
"csel %0, %1, %2, hi\n"
: "+r" (val)
: "r" (a), "r" (b)
: "memory");
return val;
}
int main()
{
int val;
val = compare_data(5, 6);
printf("big data: %d\n", val);
val = compare_data(6, 4);
printf("big data: %d\n", val);
}


编译运行:

OpenEuler基础实验_文件句柄_22