赞
踩
最近在弄音视频上云,参考了腾讯云中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
关于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; }
下面再给出私钥加密,公钥解密的例子,如下:
取明文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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。