: This article mainly introduces the opensslrsa key format and solves the key format issues for php and c ++ collaborative development. For more information about PHP tutorials, see. OpenSSL programming-RSA programming
This article was published by maxcompute in June 26, 2014. Views: 1,954, comments: 0
I. 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 -----
II. OpenSSL key-related commands
1. generate a key
Openssl genrsa-out key. pem 1024
-Out: specifies the file to be generated. The file contains the public key and private key. Therefore, the file can be encrypted or decrypted.
1024 length of the generated key
2. extract the PEM public key
Openssl rsa-in key. pem-pubout-out pubkey. pem
-In: specifies the input key file.
-Out: specifies to extract the file that generates the public key (in the 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 to extract the file that generates the public key (in PEM RSAPublicKey format)
4. Public Key Encryption File
Openssl rsautl-encrypt-in input. file-inkey pubkey. pem-pubin-out output. file
-In: specifies the encrypted file.
-Inkey: specifies the encryption public key file.
-Pubin 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.
III. RSA APIs
1. basic data structure
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;
2. BN large number series functions
// Generate a new BIGNUM structure
BIGNUM * BN_new (void );
// Release a BIGNUM structure. after the release, a = NULL;
Void BN_free (BIGNUM * );
// Initialize all items as 0, usually BN _ init (& c)
Void BN_init (BIGNUM *);
// Assign 0 to all items in a, but the memory is not released
Void BN_clear (BIGNUM * );
// It is equivalent to combining BN_free and BN_clear. do not assign 0 values, or release space.
Void BN_clear_free (BIGNUM * );
// Set the number a to the integer w.
Int BN_set_word (BIGNUM * a, unsigned long w );
// If the large number a can be expressed as long, a long number is returned.
Unsigned long BN_get_word (BIGNUM * );
// Generate a pseudo-random number of strong bits for encryption
// If top =-1, the highest bit is 0, top = 0, the highest bit is 1, top = 1, the highest bit and the next high are 1, bottom is true, and the random number is even
Int BN_rand (BIGNUM * rnd, int bits, int top, int bottom );
// Convert a into a string and store it to. the space to must be greater than BN_num_bytes ()
Int BN_bn2bin (const BIGNUM * a, unsigned char * );
// Convert the positive integer of the len bit in s to a large number
BIGNUM * BN_bin2bn (const unsigned char * s, int len, BIGNUM * ret );
// Convert large numbers into hexadecimal strings
Char * BN_bn2hex (const BIGNUM * );
// Convert a large number into a 10-digit string
Char * BN_bn2dec (const BIGNUM * );
// Convert a hexadecimal string to a large number.
Int BN_hex2bn (BIGNUM ** a, const char * str );
// Upload a 10-digit string to 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 modeled as num. e is the public encryption index, which is generally 65537 (0x10001)
RSA * RSA_generate_key (int num, unsigned long e, void (* callback) (int, int, void *), void * cb_arg );
// Returns the number of digits of the RSA modulo.
Int RSA_size (const RSA * rsa );
// Test whether p and q are prime numbers.
Int RSA_check_key (RSA * rsa );
4. PEM series functions
// Load the public key certificate in RSAPublicKey format from the file
RSA * PEM_read_RSAPublicKey (FILE * fp, RSA ** x, pem_password_cb * cb, void * u );
// Reload the public key certificate in RSAPublicKey format from 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: length of the information to be encrypted
From: to encrypt information
To: encrypted information
Padding: the encryption scheme adopted. it can be 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 the information to be decrypted
From: information to be decrypted
To: decrypted information
Padding: decryption scheme adopted
IV. RSA programming example
1. data encryption and decryption examples
# Include
# Include
# Include
# Include
# Include
# Include
# Define PRIKEY "prikey. pem"
# Define PUBKEY "pubkey. pem"
# Define BUFFSIZE 4096
/*************************************** *********************************
* RSA encryption and decryption functions
*
* File: test_rsa_encdec.c
* Gcc-Wall-O2-o test_rsa_encdec test_rsa_encdec.c-lcrypto-lssl
*
* Author: tonglulin@gmail.com bywww.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. the PUBKEY format PEM uses the PEM_read_RSA_PUBKEY function */
If (rsa = PEM_read_RSAPublicKey (fp, 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;
}
RSA_free (rsa );
Fclose (fp );
Return en;
}
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 ){
Return NULL;
}
If (rsa = pem_read_rs1_vatekey (fp, NULL) = NULL ){
Return 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;
}
RSA_free (rsa );
Fclose (fp );
Return de;
}
Int main (int argc, char * argv [])
{
Char * src = "hello, world! ";
Char * en = NULL;
Char * de = NULL;
Printf ("src is: % s \ n", src );
En = my_encrypt (src, PUBKEY );
Printf ("enc is: % s \ n", en );
De = my_decrypt (en, PRIKEY );
Printf ("dec is: % s \ n", de );
If (en! = NULL ){
Free (en );
}
If (de! = NULL ){
Free (de );
}
Return 0;
}
2. PEM/BIGNUM public key conversion example
# 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 bywww.qmailer.net
**************************************** ********************************/
Const char * n = "bytes ";
Const char * pubkey = "----- begin rsa public key ----- \ Users + users + 8dOeySRdVz1m5/rCWPhuKwgWxr \ Users/dtlXiU + 1aSg + users/g8BjQ6WhF3yQ \ Users + users = \ 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 args \ n", argv [0]);
Return-1;
}
/* Convert PEM to a large number of strings */
If (strcasecmp (argv [1], "bignum") = 0 ){
If (argc = 3 ){
/* Read from external files */
Fp = fopen (argv [2], "r ");
If (fp = NULL ){
Return-1;
}
Rsa = PEM_read_RSAPublicKey (fp, & rsa, NULL, NULL );
If (rsa = NULL ){
Return-1;
}
}
Else {
/* Read data from memory */
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 \ n", BN_bn2hex (rsa-> n ));
Printf ("% s \ n", BN_bn2hex (rsa-> e ));
If (argc = 3 ){
Fclose (fp );
}
Else {
BIO_free (bio );
}
RSA_free (rsa );
}
/* Convert a large number of strings to a PEM file */
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;
/* Set the module */
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. example of key generation
# Include
# Include
# Include
# 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 bywww.qmailer.net
**************************************** ********************************/
Int main (int argc, char * argv [])
{
/* Generate an RSA Key */
RSA * rsa = RSA_generate_key (1024,655 37, NULL, NULL );
Printf ("BIGNUM: % s \ n", BN_bn2hex (rsa-> n ));
/* Extract the private key */
Printf ("PRIKEY: \ n ");
Pem_write_rs1_vatekey (stdout, rsa, NULL, NULL, 0, NULL, NULL );
/* Extract the 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 preceding section introduces the openssl rsa key format and solves the key format issues for php and c ++ collaborative development, including the following content, if you are interested in PHP tutorials.