First recently received a project, this project needs to use the RSA encryption decryption, because did not contact before, in the Internet to find some information, and then after their own test found that the use of OpenSSL to add decryption is very simple, but on-line Baidu out of a lot is the same, sometimes help is not very big, So just want to write down their own in the entire encryption process encountered some problems, convenient to look back later, may also help to meet the same children's shoes.
Needless to say, I received this project, there are several places need to use RSA encryption and decryption. 1. Use the private key signature in the. pfx format. 2. Use the public key file of the. cer for cryptographic operations. 3, using the given exponent and the module for public key encryption. Here are some of their own code from the online collation, welcome criticism.
1. Use the private key in the. pfx format to sign (part of the Code source online):
/** <pre name= "code" class= "CPP" ><pre name= "code" class= "CPP" >* Srcdata: Strings that need to be encrypted
* Pripath: Private key file (. pfx format) * PassWd: Private key file Password * SignData: result */int signdatabypri (char *srcdata,char *pripath,char *pass Wd,char *signdata) {int err; unsigned int siglen; unsigned char sigbuf[128]; Evp_md_ctx Mdctx; Evp_pkey *pkey = NULL; FILE *FP = NULL; X509 *x509 = NULL; PKCS12 *p12 = NULL; Stack_of (X509) *ca = NULL; if (Srcdata = = NULL | | Pripath = = NULL) {return false; } ssleay_add_all_algorithms (); Err_load_crypto_strings (); if (! ( Fp = fopen (Pripath, "RB")) {printf ("Failed to read key file \ n"); return false; } P12 = D2I_PKCS12_FP (FP, NULL); Fclose (FP); if (! P12) {printf ("Failed to read key file \ n"); return false; } if (! Pkcs12_parse (P12, PassWd, &pkey, &x509, &ca)) {printf ("The unpacking key failed \ n"); Pkcs12_free (P12); return false; } pkcs12_free (P12); if (Pkey = = NULL) {printf ("The unpacking key failed \ n"); return false; }/* Signature data */Evp_signinit (&mdctx, EVP_SHA1 ()); //Signature Algorithm Select SHA1 evp_signupdate (&mdctx, Srcdata, strlen (Srcdata)); Siglen = 128; memset (sigbuf,0x00,sizeof (SIGBUF)); Err = evp_signfinal (&mdctx, Sigbuf, &siglen, Pkey); if (err! = 1) {printf ("signature failed \ n"); /* Release the dependent variable */if (Pkey) {evp_pkey_free (Pkey); } if (X509) {x509_free (X509); } return false; } memcpy (SignData, Sigbuf, Siglen); /* Release the dependent variable */if (Pkey) {evp_pkey_free (Pkey); } if (X509) {x509_free (X509); } return true;
2. Use the public key file of the. cer to encrypt the string:
/** src: Source string required for encryption * LEN:SRC length * Path_key: Path to public key file (. cer format) */int rsaencrypt (char *str,int len,char *path_key,char *en c) {char *p_en; RSA *p_rsa; FILE *file; int Flen,rsa_len; pkcs12* p12 = NULL; X509 * x509 = NULL; Stack_of (X509) *ca = NULL; Evp_pkey * PKEY = NULL; if ((File=fopen (Path_key, "R")) ==null) {perror ("Open key file Error"); return 0; } bio* B; B=bio_new_file (Path_key, "R"); X509 = pem_read_bio_x509 (b, NULL, NULL, NULL); if (x509 = = NULL) {printf ("read key file \ n"); ERR_PRINT_ERRORS_FP (stderr); return 0; } printf ("Read key file [%d]\n", __line__); Pkey=x509_get_pubkey (X509); Turn Evp_key into RSA key (this step is important) P_rsa = evp_pkey_get1_rsa (PKEY); Rsa_len=rsa_ Size (P_rsa); p_en= (unsigned char *) malloc (rsa_len+1); memset (p_en,0,rsa_len+1) ; Web Mountain Many examples of this function call when the first argument uses the length of the key is because they use rsa_no_padding encryption method, such as using rsa_pkcs1_pAdding,len Required Source String length if (Rsa_public_encrypt (len,str,p_en,p_rsa,rsa_pkcs1_padding) <0) { printf ("Encryption failed \ n"); return 0; } memcpy (Enc,p_en,rsa_len); fclose (file); free (p_en); return Rsa_len;}
3. Using the given exponent and module for public key encryption
/** type: generally divided into 10 and 16 binary * BNN: modulo, binary number and type corresponding to * Bne: usually divided into two rsa_f4 and rsa_3 (in RSA.H definition) * In: Need to encrypt the source data * out: Encrypted ciphertext */int RSAENCRYP Tbymodule (int type,char *bnn,int bne,unsigned char *in,unsigned char *out) {int ret, flen; Bignum *bnn, *bne, *bnd; unsigned char *out_buf; BNN = Bn_new (); BNE = Bn_new (); BND = Bn_new (); Switch (type) {case 10:bn_dec2bn (&BNN, BNN); Bn_set_word (BNE, BNE); Break Case 16:bn_hex2bn (&BNN, BNN); Bn_set_word (BNE, BNE); Break default:printf ("Err type\n"); return-1; } RSA *r = Rsa_new (); R->n = BNN; R->e = BNE; R->d = BND; Flen = Rsa_size (R); Out_buf = (unsigned char *) malloc (Flen); memset (out_buf, 0, Flen); <pre name= "code" class= "CPP" >//Web Mountain Many examples of this function call when the first argument uses the length of the key is because they encrypt the use of rsa_no_padding, such as the use of rsa_pkcs1_padding, Len needs to fill in the source string length ret = Rsa_public_encrypt (strlen (in), In,out_buf,r,rsa_pkcs1_padding); if (Ret < 0) {printf ("Encrypt failed!\n"); return ret; } mem CPY (Out,out_buf,ret); free (out_buf); Rsa_free (R); return ret ;}
There are some such as SHA1 do the signature, base64 transcoding and other operations do not repeat, the Internet is also a lot of code and interpretation.
OpenSSL Plus Decryption Learning notes