当前位置:   article > 正文

openssl公钥加密私钥解密和私钥加密公钥解密_openssl为什么不能私钥机密

openssl为什么不能私钥机密

最近在弄音视频上云,参考了腾讯云中SecretId和SecretKey,直观理解SecretKey是私钥,用于签名,然后公钥验证签名,个人理解SecretId在腾讯云系统里面有一条记录,此记录存放着公钥信息。

关于公钥,私钥,一般认为是公钥加密,私钥解密;私钥签名,公钥验签,如下所示:

生成公钥私钥
openssl genrsa -out RSAPrivateKey.pem  1024
openssl rsa -in RSAPrivateKey.pem -out RSAPublicKey.pem -pubout

公钥加密
openssl rsautl -encrypt -in hello.txt -inkey RSAPublicKey.pem -pubin -out hello.txt.encrypt
私钥解密
openssl rsautl -decrypt -in hello.txt.encrypt -inkey RSAPrivateKey.pem -out hello.txt.decrypt



私钥签名
openssl dgst -sha1 -sign RSAPrivateKey.pem -out sign.txt.signed sign.txt
公钥验签
openssl dgst -sha1 -verify RSAPublicKey.pem -signature sign.txt.signed sign.txt
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

关于openssl,没有提供关于私钥加密,公钥解密的命令行,但是却有相关的函数。
私钥签名本身是个加密过程,公钥验签也存在着解密过程。

rsa加密时,有六个重要的数:
质数:p
质数:q
模数:n=pq
欧拉函数: ϕ \phi ϕ(n)=(p-1)
(q-1)
公钥指数e:其中e满足1<e< ϕ \phi ϕ(n),并且e与 ϕ \phi ϕ(n)互质
私钥指数d:满足ed ≡ \equiv 1(mod ϕ \phi ϕ(n))

例如,取p=3,q=11,则n=33, ϕ \phi ϕ(n)=20,取e=3,计算出d=7。

首先给出例子,公钥加密,私钥解密:
取明文m=2,利用加密公式me ≡ \equiv c(mod n),将m=2,e=3,n=33代入公式,得到
23 ≡ \equiv c(mod 33),求得密文c=8。

然后再利用解密公式cd ≡ \equiv m2(mod n),将c=8,d=7,n=33代入公式,得到
87 ≡ \equiv m2(mod 33),求得明文m2=2

如下是代码展示,applink.c是openssl中自带的c文件,需要将此c文件拷贝到头文件下,否则执行时会出问题。

// OpensslTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

#ifdef __cplusplus

extern "C" {
#endif

#include <openssl/applink.c>

#ifdef __cplusplus
}

#endif

int main()
{
	// 原始明文
	unsigned char plain[256] = "hello123";

	// 用来存放密文
	unsigned char encrypted[1024];

	// 用来存放解密后的明文
	unsigned char decrypted[1024];

	// 公钥和私钥文件
	const char* pub_key = "RSAPublicKey.pem";
	const char* priv_key = "RSAPrivateKey.pem";

	// -------------------------------------------------------
	// 利用公钥加密明文的过程
	// -------------------------------------------------------

	// 打开公钥文件
	FILE* pub_fp = fopen(pub_key, "r");
	if (pub_fp == NULL) {
		printf("failed to open pub_key file %s!\n", pub_key);
		return -1;
	}

	// 从文件中读取公钥
	RSA* rsa1 = PEM_read_RSA_PUBKEY(pub_fp, NULL, NULL, NULL);
	//RSA* rsa1 = PEM_read_RSAPublicKey(pub_fp, NULL, NULL, NULL);
	if (rsa1 == NULL) {
		printf("unable to read public key!\n");
		return -1;
	}

	/*
	if (strlen(plain) >= RSA_size(rsa1) - 41) {
		printf("failed to encrypt\n");
		return -1;
	}
	*/

	fclose(pub_fp);

	int iLenPlain = strlen((const char *)plain);

	// 用公钥加密
	int len = RSA_public_encrypt(iLenPlain, plain, encrypted, rsa1, RSA_PKCS1_PADDING);
	if (len == -1) {
		printf("failed to encrypt\n");
		return -1;
	}

	// 输出加密后的密文
	FILE* fp = fopen("out.txt", "w");
	if (fp) {
		fwrite(encrypted, len, 1, fp);
		fclose(fp);
	}
	// -------------------------------------------------------
	// 利用私钥解密密文的过程
	// -------------------------------------------------------
	// 打开私钥文件
	FILE* priv_fp = fopen(priv_key, "r");
	if (priv_fp == NULL) {
		printf("failed to open priv_key file %s!\n", priv_key);
		return -1;
	}


	// 从文件中读取私钥
	RSA *rsa2 = PEM_read_RSAPrivateKey(priv_fp, NULL, NULL, NULL);
	if (rsa2 == NULL) {
		printf("unable to read private key!\n");
		return -1;
	}

	// 用私钥解密
	len = RSA_private_decrypt(len, encrypted, decrypted, rsa2, RSA_PKCS1_PADDING);
	if (len == -1) {
		printf("failed to decrypt!\n");
		return -1;
	}
	fclose(priv_fp);


	// 输出解密后的明文
	decrypted[len] = 0;
	printf("%s\n", decrypted);

	return 0;
}



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

下面再给出私钥加密,公钥解密的例子,如下:
取明文m=2,利用加密公式md ≡ \equiv c(mod n),将m=2,d=7,n=33代入公式,得到
27 ≡ \equiv c(mod 33),求得密文c=29。

然后再利用解密公式ce ≡ \equiv m2(mod n),将c=29,e=3,n=33代入公式,得到
293 ≡ \equiv m2(mod 33),求得明文m2=2

// OpensslTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

#ifdef __cplusplus

extern "C" {
#endif

#include <openssl/applink.c>

#ifdef __cplusplus
}

#endif

int main()
{
	// 原始明文
	unsigned char plain[256] = "hello123";

	// 用来存放密文
	unsigned char encrypted[1024];

	// 用来存放解密后的明文
	unsigned char decrypted[1024];

	// 公钥和私钥文件
	const char* pub_key = "RSAPublicKey.pem";
	const char* priv_key = "RSAPrivateKey.pem";

	// 打开公钥文件
	FILE* pub_fp = fopen(pub_key, "r");
	if (pub_fp == NULL) {
		printf("failed to open pub_key file %s!\n", pub_key);
		return -1;
	}

	// 从文件中读取公钥
	RSA* rsa1 = PEM_read_RSA_PUBKEY(pub_fp, NULL, NULL, NULL);
	//RSA* rsa1 = PEM_read_RSAPublicKey(pub_fp, NULL, NULL, NULL);
	if (rsa1 == NULL) {
		printf("unable to read public key!\n");
		return -1;
	}

	fclose(pub_fp);

	/*
	if (strlen(plain) >= RSA_size(rsa1) - 41) {
		printf("failed to encrypt\n");
		return -1;
	}
	*/
	// 打开私钥文件
	FILE* priv_fp = fopen(priv_key, "r");
	if (priv_fp == NULL) {
		printf("failed to open priv_key file %s!\n", priv_key);
		return -1;
	}


	// 从文件中读取私钥
	RSA *rsa2 = PEM_read_RSAPrivateKey(priv_fp, NULL, NULL, NULL);
	if (rsa2 == NULL) {
		printf("unable to read private key!\n");
		return -1;
	}

	fclose(priv_fp);


	int iLenPlain = strlen((const char *)plain);

	// 用私钥加密
	int len = RSA_private_encrypt(iLenPlain, plain, encrypted, rsa2, RSA_PKCS1_PADDING);
	if (len == -1) {
		printf("failed to encrypt\n");
		return -1;
	}

	// 输出加密后的密文
	FILE* fp = fopen("out.txt", "w");
	if (fp) {
		fwrite(encrypted, len, 1, fp);
		fclose(fp);
	}

	

	// 用公钥解密
	len = RSA_public_decrypt(len, encrypted, decrypted, rsa1, RSA_PKCS1_PADDING);
	if (len == -1) {
		printf("failed to decrypt!\n");
		return -1;
	}
	


	// 输出解密后的明文
	decrypted[len] = 0;
	printf("%s\n", decrypted);

	return 0;
}



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/308352
推荐阅读
相关标签
  

闽ICP备14008679号