c - 如何使用 MPI 修复 C 中的 AES 解密
问题描述
目前我正在尝试使用 MPI 将特定的加密数据从一个处理器传递到另一个处理器,仅使用 2 个处理器来检查加密或解密是否有效。我有一个 int 值,它被转换为字符串进行加密,然后发送到处理器等级 1。我在处理器中正确接收字符串,但是当我调用解密函数时,它似乎没有给我明文。我已经从https://github.com/kokke/tiny-AES-C下载了 AES 代码
int size,rank;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int data = 532123;
uint8_t data_file[10];
uint8_t key[1] = {50};
int data_decrypt;
uint8_t iv[1] = {1};
struct AES_ctx ctx;
if (rank == 0) {
sprintf((char *) data_file, "%d", data);
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen((char *) data_file));
printf("Sending in 0: %s\n",(char*) data_file);
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1: %s\n",(char*)data_file);
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen((char*)data_file));
printf("DEC at Rank 1: %s\n",(char*) data_file);
}
MPI_Finalize();
return 0;
解决方案
首先我们必须安装需求。 看到这个链接
成功安装需求后,我们运行简单的 hello world MPI。
你好世界!
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Print off a hello world message
printf("Hello world from processor %s, rank %d out of %d processors\n",
processor_name, world_rank, world_size);
// Finalize the MPI environment.
MPI_Finalize();
}
编译并运行
$ mpicc mhello.c -o mhello
$ mpirun -np #numberOfProcess ./mhello
成功运行此代码后,您可以更进一步。
并返回原始问题。
我认为您对项目 AES 部分的使用是错误的。
通过执行一些更改和使用
AES_ECB_decrypt(&ctx, data_file);
AES_ECB_encrypt(&ctx, data_file);
作品。
项目的 GitHub 页面说如何使用 Enc 和 Dec 函数见
使用上述 main 的第二个重要更改struct AES_ctx ctx;
只执行一次。
这是代码的工作版本。
mpi-hello.c
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "aes.h"
/*
* compile
* mpicc mpi-hello.c aes.c -o mpi-hello
*
* Run
* mpirun -np 2 executable
*
*
*
* */
struct AES_ctx ctx;
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int main(int argc, char** argv) {
int size,rank=0;
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int data = 532123;
uint8_t data_file[10];
printf("this is in main\n");
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
//encrypt data
AES_ECB_encrypt(&ctx, data_file);
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,16,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,16,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
AES_ECB_decrypt(&ctx, data_file);
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
MPI_Finalize();
}
重要笔记
- 将
aes.c
源文件放在原始源的同一文件夹中,即:mpi-hello.c
编译代码
mpicc mpi-hello.c aes.c -o mpi-hello
运行:
mpirun -np 2 ./mpi-hello
- 我发现
MPI_Send
必须将第二个参数更改为16
,但是为什么呢?
附言。
在基于 Debian 的系统上从存储库安装不起作用,我必须从源代码构建它。
将字符串转换为 int的原始来源我知道这可能不是最好的解决方案,但可以工作。
如何运行MPI。
- 快速 MPI C教程
编辑 1
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "aes.h"
/*
* compile
* mpicc mpi-hello.c aes.c -o mpi-hello
*
* Run
* mpirun -np 2 executable
*
*
*
* */
struct AES_ctx ctx;
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int main(int argc, char** argv) {
int size,rank=0;
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int data = 532123;
uint8_t data_file[10];
printf("this is in main\n");
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
//encrypt data
//AES_ECB_encrypt(&ctx, data_file);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
//AES_ECB_decrypt(&ctx, data_file);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
MPI_Finalize();
}
编辑 2
在评论中申请请求。
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "aes.h"
/*
* compile
* mpicc mpi-hello.c aes.c -o mpi-hello
*
* Run
* mpirun -np 2 executable
*
*
* */
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int main(int argc, char** argv) {
int size,rank=0;
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int data = 532123;
uint8_t data_file[10];
//start Crypto Section
//~ key and iv
///
uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
///
struct AES_ctx ctx;
printf("this is in main\n");
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
///Enc
//set
AES_init_ctx_iv(&ctx, key, iv);
//enc
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
///Dec
//set
AES_init_ctx_iv(&ctx, key, iv);
//dec
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
MPI_Finalize();
}
编辑 3
将 key 和 iv 放在 if else 部分。
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
//~ key and iv
///
uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
///
///Enc
//set
AES_init_ctx_iv(&ctx, key, iv);
//enc
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
//~ key and iv
///
uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
///
///Dec
//set
AES_init_ctx_iv(&ctx, key, iv);
//dec
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
例如,您可以更改密钥的第一个元素,即:0x60 -> 0x61
在 if 或 else not both,然后重新编译并运行程序以查看接收者是否没有正确的密钥,他/她无法解码您的加密数据。
[去做]
- 添加更多关于 AES 的解释。
推荐阅读
- sql-server-2012 - 检查日期列的约束作为格式明智地在插入期间检查其有效日期
- tensorflow - 从 Tensorflow 获取匹配标签的位置?
- python-2.7 - Python-Pandas - AttributeError:'Index' 对象没有属性'inferred_freq' -
- angular - Angular Material - Datepicker 从所选值中获取一个月的最大值
- codenameone - 代号中的后台线程
- c# - 如何将绘图图形保存到位图?
- objective-c - 像素处理的快速性能
- python - 根据传递的参数数量更改返回值的数量
- php - 在 Laravel 中不工作 Request::is()
- javascript - 在ajax中动态附加的元素上添加jquery事件