Home  >  Article  >  Backend Development  >  The problem of openssl rsa key format solves the key format problem of collaborative development of php and c++

The problem of openssl rsa key format solves the key format problem of collaborative development of php and c++

WBOY
WBOYOriginal
2016-08-08 09:24:222957browse

OpenSSL Programming - Detailed Explanation of RSA Programming
This article was published by Da Tong on June 26, 2014, viewed: 1,954 times, comments: 0

1. RSA PEM file format

1. PEM private key format file
-- ---BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

2. PEM public key format file
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----

3. PEM RSAPublicKey public key format file
-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY- ----

2. OpenSSL key related commands

1. Generate key
openssl genrsa -out key.pem 1024
-out specifies the generated file. This file contains the public key and the private key, so you can Encryption and decryption
1024 The length of the generated key

2. Extract the PEM format public key
openssl rsa -in key.pem -pubout -out pubkey.pem
-in specifies the input key file
-out specifies the extraction Generate a public key file (PEM public key format)

3. Extract the PEM RSAPublicKey format public key
openssl rsa -in key.pem -RSAPublicKey_out -out pubkey.pem
-in specifies the input key file
-out specifies the extraction Generate public key file (PEM RSAPublicKey format)

4. Public key encryption file
openssl rsautl -encrypt -in input.file -inkey pubkey.pem -pubin -out output.file
-in Specify the encrypted file
- inkey specifies the encrypted public key file
-pubin The surface is encrypted with a pure public key file
-out specifies the encrypted file

5. Private key decryption file
openssl rsautl -decrypt -in input.file -inkey key.pem -out output.file
  -in specifies the file to be decrypted
  -inkey specifies the private key file
  -out specifies the decrypted file

3. RSA related API

1. Basic data structure
struct {
  BIGNUM *n;                      public modulus
BIGNUM *e; // public exponent
BIGNUM *d; // private exponent
BIGNUM *p; // secret prime factor
BIGNUM *dmp1; // d mod ( p-1)
BIGNUM *dmq1; // d mod (q-1)
BIGNUM *iqmp; Function
//Generate a new BIGNUM structure
BIGNUM *BN_new(void);

//Release a BIGNUM structure, after release a=NULL;

void BN_free(BIGNUM *a);

//Initialize all items is 0, usually BN_ init(&c)
void BN_init(BIGNUM *);

//Assign all items in a to 0, but the memory is not released
void BN_clear(BIGNUM *a);

// It is equivalent to combining BN_free and BN_clear, either assigning a value of 0 or releasing space.
void BN_clear_free(BIGNUM *a);

//Set the large number a to an integer w
int BN_set_word(BIGNUM *a, unsigned long w);

//If the large number a can be expressed as a long type, then return a long type number
unsigned long BN_get_word(BIGNUM *a);

//Generate a pseudo-random number with strong bits for encryption
//If top=-1, the highest bit is 0, top=0, the highest bit is 1 ,top=1, the highest and second highest bits are 1, bottom is true, and the random number is an even number

int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);


//Convert a into a string for storage Enter to, the space of to must be larger than BN_num_bytes(a)

int BN_bn2bin(const BIGNUM *a, unsigned char *to);


//Convert the len-digit positive integer in s into a large number
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);

//Convert large numbers to hexadecimal strings
char *BN_bn2hex(const BIGNUM *a);

//Convert large numbers to decimal String
char *BN_bn2dec(const BIGNUM *a);

//Convert hexadecimal string to large number
int BN_hex2bn(BIGNUM **a, const char *str);

//Convert decimal Pass the string into a large number
int BN_dec2bn(BIGNUM **a, const char *str);

3. RSA series functions
//Initialize an RSA structure

RSA * RSA_new(void);


//Release an RSA Structure
void RSA_free(RSA *rsa);

//RSA private key generation function
//Generate a key pair modulo num bits, e is the public encryption index, generally 65537 (0x10001)
RSA *RSA_generate_key (int num, unsigned long e,void (*callback)(int,int,void *), void *cb_arg);

//Judge the number of digits function, return the number of digits in the RSA module
int RSA_size(const RSA *rsa);

//Test whether p and q are prime numbers
int RSA_check_key(RSA *rsa);

4. PEM series Function
//Load the RSAPublicKey format public key certificate from the file
RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u);

//Reload the RSAPublicKey format public key certificate from the BIO
RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x, pem_password_cb *cb, void *u);

//Output the RSAPublicKey public key certificate to the file
int PEM_write_RSAPublicKey(FILE *fp, RSA *x);

// Output the RSAPublicKey public key certificate to BIO
int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x);

5. RSA encryption API
int RSA_public_encrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding );

Parameter description:
flen: the length of the information to be encrypted
from: the information to be encrypted
to: the encrypted information
padding: the encryption scheme adopted, divided into: RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_SSLV23_PADDING, RSA_NO_PADDING

6.RSA Decryption API
int RSA_private_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);

Parameter description:
flen: length of information to be decrypted
from: information to be decrypted
to: Decrypted information
padding: Decryption scheme adopted

IV. RSA programming example

1. Data encryption, encryption and decryption example
#include
#include
#include
#include
#include
#include

#define PRIKEY "prikey.pem"
#define PUBKEY "pubkey.pem "
#define BUFFSIZE 4096

/***************************************************** ************************
* RSA encryption and decryption function
*
* file: test_rsa_encdec.c
* gcc -Wall -O2 -o test_rsa_encdec test_rsa_encdec.c -lcrypto -lssl
*
* author: tonglulin@gmail.com by www.qmailer.net
************************************************ ****************************/

char *my_encrypt(char *str, 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;
}

/* Read the public key PEM, PUBKEY format PEM uses the PEM_read_RSA_PUBKEY function */
if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) == NULL) {
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;

char *my_decrypt(char *str, char *prikey_path)

{
RSA *rsa = NULL;

FILE *fp = NULL;

char *de = NULL;
int rsa_len = 0;

if ((fp = fopen(prikey_path, "r")) == NULL) {
                                                                                                                                                             """"""
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;

}


int main(int argc, char *argv[])
{

char *src = "hello, world!";

char *en = NULL;

char *de = NULL;


printf("src is: %sn", src);

    en = my_encrypt(src, PUBKEY);
    printf("enc is: %sn", en);

    de= my_decrypt(en, PRIKEY);
    printf("dec is: %sn", de);

    if (en != NULL) {
        free(en);
    }

    if (de != NULL) {
        free(de);
    }

    return 0;
}
 
2. PEM/BIGNUM公钥转换示例
 #include
#include

#include
#include

/***************************************************** **********************
* RSA PEM/BIGNUM public key conversion function
*
* file: test_rsa_pubkey.c
* gcc -Wall -O2 -o test_rsa_pubkey test_rsa_pubkey .c -lcrypto -lssl
*
* author: tonglulin@gmail.com by www.qmailer.net
************************************************ ****************************/

const char *n = "C7301B330C4E123E4FA9F54F49121E8CE07974D8BFEF1D39EC9245D573D66E7FAC258F86E2B0816C6BA875F10673E655E6A8DF48DEFDDB655E253ED5A4A0FBAD50D68E91D0459F9F2377BB8CA1583E3F83C06343A5A1177C903F498A6D14015CC975522BE4446CD1EB87E88EF05A863AF0DD7C4D413CF603EDF4893EEC063BE3";

const char *pubkey = "-----BEGIN RSA PUBLIC KEY-----nMIGJAoGBAMcwGzMMThI+T6n1T0kSHozgeXTYv+8dOeySRdVz1m5/rCWPhuKwgWxrnqHXxBnPmVeao30je/dtlXiU+1aSg+61Q1o6R0EWfnyN3u4yhWD4/g8BjQ6WhF3yQnP0mKbRQBXMl1UivkRGzR64fojvBahjrw3XxNQTz2A+30iT7sBjvjAgMBAAE=n-----END RSA PUBLIC KEY-----";

int main(int argc, char *argv[])
{
    RSA    *rsa = NULL;
    BIO    *bio = NULL;
    BIGNUM *bne = NULL;
    BIGNUM *bnn = NULL;
    FILE *fp = NULL;
    unsigned long e = 65537;

    if (argc < 2) {
        printf("%s pem|bignum argsn", 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("%sn", BN_bn2hex(rsa->n));
        printf("%sn", BN_bn2hex(rsa->e));

                                                                                                                                                                             rsa);
}
/* Convert large number string to PEM file*/
else if (strcasecmp(argv[1], "pem") == 0) {

bne = BN_new();
if (bne == NULL) {
return -1;
}

bnn = BN_new( );

                                                                                 ULL) {
             BN_free(bnn);
           BN_free( bne);
                                                                                              BN_set_word(bne, e);

    if (argc == 3) {

          BN_hex2bn(&bnn, argv[2]);
                                                                PEM_write_RSAPublicKey(stdout, rsa);

RSA_free(rsa);
}

else {

                                                                                                  """"""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" ;
#include
#include
#include

/***************************************************** ************************

* RSA key generation function

*
* file: test_rsa_genkey.c

* gcc -Wall -O2 -o test_rsa_genkey test_rsa_genkey.c - lcrypto

*
* author: tonglulin@gmail.com by www.qmailer.net
************************************************ ****************************/
int main(int argc , char *argv[])
{
/* Generate RSA key*/
RSA *rsa = RSA_generate_key(1024, 65537, NULL, NULL);

printf("BIGNUM: %sn", BN_bn2hex(rsa-> ;n));

/* Extract private key*/

printf("PRIKEY:n");
PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, NULL, NULL);

/* Extract public key* /
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: n");
PEM_write_RSAPublicKey(stdout, pubrsa);

RSA_free(rsa);
RSA_free(pubrsa);

return 0;
}


The above introduces the problem of openssl rsa key format, solves the key format problem of collaborative development of PHP and C++, including aspects of the content, I hope it will be helpful to friends who are interested in PHP tutorials.


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:CentOS65 builds LNMPNext article:CentOS65 builds LNMP