openssl rsa鍵フォーマットの問題は、php/javaとc++が共同開発した鍵フォーマットの問題を解決しました。


回転:https://yq.aliyun.com/php/77737
OpenSSLプログラミング-RSAプログラミングの詳細 2014年06月26日に発表された本記事は、1,954回、コメント:0条
一.RSA PEMファイルフォーマット  1.PEM秘密鍵フォーマットファイル -----BEGIN RSA PRIVATE KEY-----END RSA PRIVATE KEY-----  2.PEM公開鍵フォーマットファイル -----BEGIN PUBLIC KEY-----END PUBLIC KEY-----  3.PEM RSAPublicKey公開鍵フォーマットファイル -----BEGIN RSA PUBLIC KEY-----END RSA PUBLIC KEY-----  二.OpenSSL鍵関連コマンド  1.鍵の生成 openssl genrsa-out key.pem 1024    -outは作成ファイルを指定しています。このファイルは公開鍵と秘密鍵の2つの部分を含んでいます。だから暗号化してもいいし、復号してもいいです。    1024生成鍵の長さ  2.PEMフォーマット公開鍵の抽出 openssl rsa-in key.pem-pubout-out pbkey.pem    -in入力する鍵ファイルを指定します。    -outは、公開鍵を生成するファイル(PEM公開鍵フォーマット)を抽出することを指定します。  3.PEM RSAPublicKeyフォーマット公開鍵を抽出する openssl rsa-in key.pem-RSAPublicKey_out-out pbkey.pem    -in入力する鍵ファイルを指定します。    -outは公開鍵を生成するファイルを抽出することを指定します。(PEM RSAPublicKeyフォーマット)  4.公開鍵暗号化ファイル openssl rsaut-encrypt-in input.file-inkey pbkey.pem-pubin-out output.file    -n暗号化されたファイルを指定します。    -inkey公開鍵ファイルの暗号化を指定します。    -pbinの表面は純粋な公開鍵ファイルで暗号化されています。    -outは暗号化されたファイルを指定します。  5.秘密鍵の復号ファイル openssl rsaut-decrypt-in input.file-inkey key.pem-out output.file    -n復号するファイルを指定します。    -inkey秘密鍵ファイルを指定する    -out復号後のファイルを指定します。  三.RSA関連API  1.基本データ構造 struct{    BIGNUM***n;              // public modulus    BIGNUM*e;              // public exponent    BIGNUM*d              // prvate exponent    BIGNUM*p;              // secret preme factor    BIGNUM*q              // secret preme factor    BIGNUM*dmp 1;           // d mod(p-1)    BIGNUM*dmq 1;           // d mod(q-1)    BIGNUM*iqmp;           // q^-1 mod p    // ... } RSA;
  2.BNの大数シリーズ関数 //BIGNUM構造BIGNUM*BN new(void)を新たに生成します。
//BIGNUM構造をリリースし、リリース後a=NULL;void BNufree(BIGNUM*a);
//初期化のすべての項は0で、一般的にBN_init(&c)void BNuinit(BIGNUM*)です。
//aのすべての項を0としたが、メモリはvoid BNuclear(BIGNUM*a)を解放していない。
//BNufreeとBNuclearを総合して、0を賦課しないと空間を解放します。void BNuclear ufree(BIGNUM*a);
//大数aを設定するのは整数w int BNusetuword(BIGNUM*a、unsigned long w);
//もし大きな数aがlong型と表示されたら、1つのlong型数unsigned long BNugutword(BIGNUM*a)を返します。
//暗号化用の強力なビッツの疑似乱数を生成する//top=-1、最高位は0、top=0、最高位は1、top=1、最高位と下位は1、bottomは真、乱数は偶数int BNurand(BIGNUM*rnd、int bitts、int top、int bottom)。
//aを文字列に変換してtoを預け入れて、toの空間はBNumubytes(a)int BNubn 2 bin(const BIGNUM*a、unsigned char*to)より大きくなければなりません。
//s中のlenビットの正の整数を大数BIGNUM*BNubin(const unsigned char*s,int len,BIGNUM*ret)に変換する;
//大きな数を16進文字列char*BNubn 2 hex(const BIGNUM*a)に変換する。  //大きな数を10進数文字列char*BNubn 2 decに変換します。
//16進数文字列を大数int BNuhex 2 bn(BIGNUM***a、const char*str)に変換する。
//10進数文字列を大数int BNudc 2 bn(BIGNUM***a、const char*str)に伝える;  3.RSAシリーズ関数 //RSA構造RSA*RSA_new(void)を初期化します。  //RSA構造void RSAfree(RSA*RSA)をリリースします。
//RSA秘密鍵生成関数/numビットの鍵ペアを生成し、eは公開された暗号化指数で、一般的には65537(0 x 10001)RSA*RSA*RSA*RSAugned long(int num,unsigned long e,void(*calback)(int,void*)、void*
//桁数関数を判断し、RSAモードの桁数を返します。
//p、qは素数int RSAucheckukey(RSA*rsa)かどうかをテストします。  4.PEMシリーズ関数 //RSAPublicKey形式の公開鍵証明書RSA*PEMuredbablicKeyをファイルからロードします。
//BIOからRSAPublicKeyフォーマットの公開鍵証明書RSA*PEM_uRSAPublicKeyを再読み込みします。
//RSAPublicKey公開鍵証明書を出力してファイルにint PEMuwriteuRSAPublicKey(FILE*fp、RSA*x)を出力します。
//RSAPublicKey公開鍵証明書を出力してBIO int PEMuwriteu ubio(BIO*bp、RSA*x)に行きます。  5.RSA暗号化API int RSA_ublic encrypt(int freen、unsigned char*from、unsigned char*to、RSA*rsa、int padding);
パラメータの説明:    flen:情報の長さを暗号化します。    from:情報を暗号化します。    ト:暗号化された情報    padding:採用された暗号化方式は、RSA___CS 1、RSA PKCS 1、UOAEP PADDING、RSA_HVLV 23、UPADDING、RSA___NOUPADDINGに分けられています。  6.RSA復号API int RSA_uplrivatechuderypt(int freen、unsigned char*from、unsigned char*to、RSA*rsa、int padding);
パラメータの説明:    flan:復号する情報の長さ    from:復号する情報    ト:復号後の情報    padding:採用した解読案  四.RSAプログラミング例1.データ加算、暗号解読例
// test_rsa_key.cpp :       "main"   。             。
//
#include "pch.h"
#include 

//https://yq.aliyun.com/php/77737

#include 
#include 
#include 
#include 
#include 
#include 

//libeay32MDd
#ifdef _DEBUG
#pragma comment(lib,"libeay32.lib")
//#pragma comment(lib,"libcrypto.lib")

#else
#pragma comment(lib,"libeay32.lib")
#endif



extern "C" {
	#include 
};




#define PRIKEY "F:\\openssl_test\\RSA2048_SK_3_privateKey.pem"
#define PUBKEY "F:\\openssl_test\\RSA2048_SK_3_publicKey.pem"


#define BUFFSIZE 4096

//#define PRIKEY "F:\\openssl_test\\RSA2048_VK_3_privateKey.pem"
//#define PUBKEY "F:\\openssl_test\\RSA2048_VK_3_publicKey.pem"



/************************************************************************
 * RSA      
 *
 * file: test_rsa_encdec.c
 * gcc -Wall -O2 -o test_rsa_encdec test_rsa_encdec.c -lcrypto -lssl
 *
 * author: [email protected] bywww.qmailer.net
 ************************************************************************/
//https://yq.aliyun.com/php/77737

char *my_encrypt(const char *str, const char *pubkey_path)
{
	RSA *rsa = NULL;
	FILE *fp = NULL;
	char *en = NULL;
	int len = 0;
	int rsa_len = 0;

	if ((fp = fopen(pubkey_path, "r")) == NULL) {
		return NULL;
	}


	/*     PEM,PUBKEY  PEM  PEM_read_RSA_PUBKEY   */
	//PEM_read_bio_RSAPublicKey();
	EVP_PKEY *evp_PKEY;
	if ((rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
	//if ((evp_PKEY = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
	//if ((rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
	//if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) == NULL) 
	{
		//return -1;
//      
		ERR_load_ERR_strings();
		ERR_load_crypto_strings();

		unsigned long errorcode = ERR_get_error();//      
		char szErrMsg[1024] = { 0 };
		char *pTmp = ERR_error_string(errorcode, szErrMsg); //   :error:errId: :  :  

		printf("OPENSSL_rsa_public_encrypt RSA_check_key failed,szErrMsg=%s", szErrMsg);
		
		const char* libname=ERR_lib_error_string(errorcode);//          
		const char* funcname=ERR_func_error_string(errorcode);//    
		const char* reason=ERR_reason_error_string(errorcode);//        
		printf("OPENSSL_rsa_public_encrypt RSA_check_key failed,szErrMsg=%s,pTmp=%s,libname=%s,funcname=%s,reason=%s",szErrMsg,pTmp,libname,funcname,reason);
		

		return NULL;
	}

	RSA_print_fp(stdout, rsa, 0);

	len = strlen(str);
	rsa_len = RSA_size(rsa);

	en = (char *)malloc(rsa_len + 1);
	memset(en, 0, rsa_len + 1);

	if (RSA_public_encrypt(rsa_len, (unsigned char *)str, (unsigned char*)en, rsa, RSA_NO_PADDING) < 0) {
		return NULL;
	}

	RSA_free(rsa);
	fclose(fp);

	return en;
}

char *my_decrypt(const char *str, const char *prikey_path)
{
	RSA *rsa = NULL;
	FILE *fp = NULL;
	char *de = NULL;
	int rsa_len = 0;

	if ((fp = fopen(prikey_path, "r")) == NULL) {
		return NULL;
	}

	if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
		return NULL;
	}
	/**
	if (!ASN1_bn_print(bp, str, x->n, m, off))
		goto err;
	if (!ASN1_bn_print(bp, s, x->e, m, off))
		goto err;
	*/


	RSA_print_fp(stdout, rsa, 0);

	rsa_len = RSA_size(rsa);
	de = (char *)malloc(rsa_len + 1);
	memset(de, 0, rsa_len + 1);

	if (RSA_private_decrypt(rsa_len, (unsigned char *)str, (unsigned char*)de, rsa, RSA_NO_PADDING) < 0) {
		return NULL;
	}

	RSA_free(rsa);
	fclose(fp);

	return de;
}

int main2(int argc, char *argv[])
{
	const char *src = "hello, world!";
	char *en = NULL;
	char *de = NULL;

	printf("src is: %s
", src); en = my_encrypt(src, PUBKEY); printf("enc is: %s
", en); de = my_decrypt(en, PRIKEY); printf("dec is: %s
", de); if (en != NULL) { free(en); } if (de != NULL) { free(de); } return 0; }
2.PEM/BIGNUM公開鍵変換例
#include "pch.h"

#include 
#include 
#include 
#include 

#define strcasecmp strcmp

/************************************************************************
 * RSA PEM/BIGNUM      
 *
 * file: test_rsa_pubkey.c
 * gcc -Wall -O2 -o test_rsa_pubkey test_rsa_pubkey.c -lcrypto -lssl
 *
 * author: [email protected] bywww.qmailer.net

       
struct {
BIGNUM *n; // public modulus
BIGNUM *e; // public exponent
BIGNUM *d; // private exponent
BIGNUM *p; // secret prime factor
BIGNUM *q; // secret prime factor
BIGNUM *dmp1; // d mod (p-1)
BIGNUM *dmq1; // d mod (q-1)
BIGNUM *iqmp; // q^-1 mod p
// ...
} RSA;
 ************************************************************************/

//rsa->n =>public modulus
const char *n = "C7301B330C4E123E4FA9F54F49121E8CE07974D8BFEF1D39EC9245D573D66E7FAC258F86E2B0816C6BA875F10673E655E6A8DF48DEFDDB655E253ED5A4A0FBAD50D68E91D0459F9F2377BB8CA1583E3F83C06343A5A1177C903F498A6D14015CC975522BE4446CD1EB87E88EF05A863AF0DD7C4D413CF603EDF4893EEC063BE3";

const char *pubkey = "-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMcwGzMMThI+T6n1T0kSHozgeXTYv+8dOeySRdVz1m5/rCWPhuKwgWxr
qHXxBnPmVeao30je/dtlXiU+1aSg+61Q1o6R0EWfnyN3u4yhWD4/g8BjQ6WhF3yQ
P0mKbRQBXMl1UivkRGzR64fojvBahjrw3XxNQTz2A+30iT7sBjvjAgMBAAE=
-----END RSA PUBLIC KEY-----"; //https://yq.aliyun.com/php/77737 int main5(int argc, char *argv[]) { RSA *rsa = NULL; BIO *bio = NULL; BIGNUM *bne = NULL; BIGNUM *bnn = NULL; FILE *fp = NULL; //rsa->e public exponent unsigned long e = 65537; if (argc < 2) { printf("%s pem|bignum args
", argv[0]); return -1; } /* PEM */ if (strcasecmp(argv[1], "bignum") == 0) { if (argc == 3) { /* */ fp = fopen(argv[2], "r"); if (fp == NULL) { return -1; } rsa = PEM_read_RSAPublicKey(fp, &rsa, NULL, NULL); if (rsa == NULL) { return -1; } } else { /* */ bio = BIO_new(BIO_s_mem()); BIO_puts(bio, pubkey); rsa = PEM_read_bio_RSAPublicKey(bio, &rsa, NULL, NULL); if (rsa == NULL) { return -1; } } RSA_print_fp(stdout, rsa, 0); printf("%s
", BN_bn2hex(rsa->n)); printf("%s
", BN_bn2hex(rsa->e)); if (argc == 3) { fclose(fp); } else { BIO_free(bio); } RSA_free(rsa); } /* PEM */ else if (strcasecmp(argv[1], "pem") == 0) { bne = BN_new(); if (bne == NULL) { return -1; } bnn = BN_new(); if (bnn == NULL) { BN_free(bne); return -1; } rsa = RSA_new(); if (rsa == NULL) { BN_free(bnn); BN_free(bne); return -1; } rsa->e = bne; rsa->n = bnn; /* */ BN_set_word(bne, e); if (argc == 3) { BN_hex2bn(&bnn, argv[2]); } else { BN_hex2bn(&bnn, n); } PEM_write_RSAPublicKey(stdout, rsa); RSA_free(rsa); }else { return -1; } return 0; }
3.鍵生成例
#include "pch.h"
#include 
#include 
#include 
#include 
#include 
#include 

/************************************************************************
 * RSA      
 *
 * file: test_rsa_genkey.c
 * gcc -Wall -O2 -o test_rsa_genkey test_rsa_genkey.c -lcrypto
 *
 * author: [email protected] bywww.qmailer.net
 ************************************************************************/
int main(int argc, char *argv[])
{
	/*   RSA   */
	RSA *rsa = RSA_generate_key(1024, 65537, NULL, NULL);

	printf("BIGNUM: %s
", BN_bn2hex(rsa->n)); /* */ printf("PRIKEY:
"); PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, NULL, NULL); /* */ unsigned char *n_b = (unsigned char *)calloc(RSA_size(rsa), sizeof(unsigned char)); unsigned char *e_b = (unsigned char *)calloc(RSA_size(rsa), sizeof(unsigned char)); int n_size = BN_bn2bin(rsa->n, n_b); int b_size = BN_bn2bin(rsa->e, e_b); RSA *pubrsa = RSA_new(); pubrsa->n = BN_bin2bn(n_b, n_size, NULL); pubrsa->e = BN_bin2bn(e_b, b_size, NULL); printf("PUBKEY:
"); PEM_write_RSAPublicKey(stdout, pubrsa); RSA_free(rsa); RSA_free(pubrsa); return 0; }
QT openssl RSA非対称暗号解読例(PEMuredbablicKey AndPEMUuradURSAuPUBKEY)
回転:https://blog.csdn.net/sinat_14854721/article/details/80310868
1:暗号化の際には、異なる言語でopensslライブラリを呼び出して生成する秘密鍵のフォーマットが異なります。     PEM公開鍵フォーマットファイル(1)-----BEGIN PUBLIC KEY-----  
         -----END PUBLIC KEY-----  
    PEM RSAPublicKey公開鍵フォーマットファイル(2)-----BEGIN RSA PUBLIC KEY-----  
-----END RSA PUBLIC KEY-----  2:この2つの異なるフォーマットの公開鍵について:異なる方法を選択して暗号化を行う:(1)PEMuradURSAUPUBKEY     最初のフォーマットに対して
(2)PEMuraduRSAPublicKey    第二のフォーマットに対して
3:暗号化を行います。公開鍵はbegin public key形式ですので、PEMuraduRSAメソッドを呼び出します。パラメータ:strは暗号化されたデータです。   ,publickukeyは公開鍵のパスです。
QByteAray http::encodeuc(char*str,char*pubkey){          RSA*rsa=NULL          FILE*fp=NULL          char*en=NULL          if((fp=fopen)==NULL)          {              return NULL          }           /* 公開鍵PEMを読み、PUBKEYフォーマットPEMはPEMを使用します。          if((RSa=PEMUURadURSA_PUBKEY(fp、NULL、NULL)==NULL)          {              return NULL          }           int rsa_ulen=RSA_size(rsa);          en=(char*)malloc(rsafun);          int reaslt=RSAupublicuencrypt(streen)、str、str、(unsigned char*)str、(unsigned char*)en、rsa、RSAuPKCS 1_PADDING);          if(reast==-1)          {              return NULL          }           RSA_free(rsa)          return QByteAray(reinterprettucast).reast.toBase 64();
4:復号する:
QByteAray http::decodeuc(char*str,char*prkeyupth){       RSA*rsa=NULL       FILE*fp=NULL       char*de=NULL       int rsa_len=0       if((fp=fopen)==NULL)       {           return“read fail”       }        if((rsa=PEMuradURSAPrivateKey(fp,NULL,NULL)==NULL)           return NULL       }        RSA___________________、RSA______ize(rsa);       de=(char*)malloc(rsafun);       int reaslt=RSA_uplivated d diecrypt(strelen)、str、(unsigned char*)str、(unsigned char*)de、rsa、RSA_PKCS 1_PADDING);       if(reast==-1)       {           return";       }        RSA_free(rsa)       fclose(fp)       return QByteAray(reinterprettucast、reaslt);