Object-c using OpenSSL for RSA bidirectional encryption and decryption

Source: Internet
Author: User
Tags begin rsa private key decrypt key string openssl openssl library


iOS system itself with the RSA encryption class has a feature, that is, encryption is one-way, that is, only public key encryption-> private key decryption, vice versa will be an error.


So many friends will have this situation, in the iOS client with public key encrypted data to the server side with the private key to decrypt no problem. But in turn, the data encrypted with the private key on the server is sent to the iOS client to decrypt with the public key, reporting 9809 or 50 errors. Your server side may be written in Java or other languages.


Many friends can not find a solution to the online case. I began to encounter such a problem, the last decisive use of the next OpenSSL, the use of OpenSSL library to solve the problem. Using OpenSSL can either use public key encryption or use the private key for encryption and the same result as the server-side decryption. Now let's just come up and do some tinkering.

In iOS to use OpenSSL need to compile OpenSSL library to use, I have compiled a direct download can be used, http://download.csdn.net/detail/kokjuis/9723109 click on the Open link


As for OpenSSL how to generate public private key, this does not write, online a lot.


After downloading the decompression, and then import into your Xcode project, not necessarily the same as my path, their own according to the situation to change their path



Then refer to the include path in the header Search paths in build settings and set the Always search User paths to Yes, as shown in the figure:





Then refer to the Lib directory in the Library Search Paths. After the general import Xcode will automatically be referenced, if there is no reference, manual reference.




Here is basically able to use the OpenSSL library encryption and decryption function, the following is a tool I wrote a class, you can refer to, is written in OC language, want to use Swift to write words is also very simple, you can change their own, here do not toss:



//  iOS uses OpenSSL generated public and private character string for RSA plus decryption
//RsaUtil.h////  Created by
Kokjuis on  16/8/19.
//

#import <Foundation/Foundation.h>
#import <openssl/rsa.h>
#import <openssl /pem.h>

@interface rsautil:nsobject
 /* Note that the RSA decryption feature is: Public key encryption-> private key decryption, private key encryption-> public key decryption. * *

+ (NSString *) encryptstring: (NSString *) content Withpublickey: (NSString *) publickey;//public key encryption
+ ( NSString *) decryptstring: (NSString *) encryptcontent Withpublickey: (NSString *) publickey;//public key decryption

+ (NSString *) EncryptString: (NSString *) content Withprivatekey: (NSString *) privatekey;//private key encryption
+ (NSString *) Decryptstring: ( NSString *) encryptcontent Withprivatekey: (NSString *) privatekey;//private key decryption

@end

RSAUTIL.M//Besttravel////Created by Kokjuis on 16/8/19. #import "RsaUtil.h" #import <Security/Security.h>//#import "GTMBase64.h" @implementation rsautil #pragma Mark-Generate public private key via public key string//via public key to generate key + (RSA *) Creatersakeywithpublickey: (NSString *) publickey{//To avoid the wording of the disagreement, if the public key has been
    With the following marked characters, first removed, followed by a uniform plus fixed format nsrange spos = [PublicKey rangeofstring:@ "-----BEGIN public KEY-----"];
    Nsrange Epos = [PublicKey rangeofstring:@ "-----End public KEY-----"]; if (spos.location!= nsnotfound && epos.location!= nsnotfound) {Nsuinteger s = spos.location + spos.length
        ;
        Nsuinteger e = epos.location;
        Nsrange range = Nsmakerange (s, e-s);
    PublicKey = [PublicKey substringwithrange:range];
    //Remove line breaks, spaces, etc. publickey = [PublicKey stringbyreplacingoccurrencesofstring:@ "\ r" withstring:@ "];
    PublicKey = [PublicKey stringbyreplacingoccurrencesofstring:@ "\ n" withstring:@ "]; PublicKey = [PublicKey stringbyreplacingoccurrencesofstring:@ "T" withstring:@ ""];
    
    PublicKey = [PublicKey stringbyreplacingoccurrencesofstring:@ "" withstring:@ "];
    
    RAS Public Key nsmutablestring * Rsa_public_key = [[nsmutablestring Alloc]initwithstring:publickey]; Read from memory, and the public key string begins with the-----begin the key-----\ n, and the end with the "\ n-----" \ "-----\ n". Otherwise, the Error:0906d06c:pem routines:PEM_read_bio:no start line [Rsa_public_key insertstring:@ "-----The BEGIN public key will appear-----
    \ n "atindex:0];
    
    [Rsa_public_key appendstring:@ \ \-----End public key-----\ n];
    BIO *bio = NULL;
    const char * chpublickey =[rsa_public_key utf8string];
    if (bio = Bio_new_mem_buf (Chpublickey,-1) = = NULL)/Read the RSA public key {return nil from the string;   RSA *rsa = pem_read_bio_rsa_pubkey (bio, NULL, NULL, NULL);
    
Obtain RSA structure return RSA from the bio structure; ///Key Generation key + (RSA *) Creatersakeywithprivatekey: (NSString *) privatekey{//To avoid the wording of the disagreement, if the private key has been marked with the following characters, first remove, after Surface unification plus fixed format nsrange Spos =[Privatekey rangeofstring:@ "-----BEGIN RSA PRIVATE KEY-----"];
    Nsrange Epos = [Privatekey rangeofstring:@ "-----End RSA PRIVATE KEY-----"]; if (spos.location!= nsnotfound && epos.location!= nsnotfound) {Nsuinteger s = spos.location + spos.length
        ;
        Nsuinteger e = epos.location;
        Nsrange range = Nsmakerange (s, e-s);
    Privatekey = [Privatekey substringwithrange:range];
    //Remove line breaks, spaces, etc. privatekey = [Privatekey stringbyreplacingoccurrencesofstring:@ "\ r" withstring:@ "];
    Privatekey = [Privatekey stringbyreplacingoccurrencesofstring:@ "\ n" withstring:@ "];
    Privatekey = [Privatekey stringbyreplacingoccurrencesofstring:@ "T" "withstring:@"];

    
    Privatekey = [Privatekey stringbyreplacingoccurrencesofstring:@ "" withstring:@ "];
    
    RAS private key nsmutablestring * Rsa_private_key = [[nsmutablestring Alloc]initwithstring:privatekey]; Reads from memory, the public key string starts with the-----begin RSA private key-----\ n, and ends with "\ n-----End RSA PrivateKEY-----\ n ". Otherwise there will be ERROR:0906D06C:PEM routines:PEM_read_bio:no start line [rsa_private_key insertstring:@-----BEGIN RSA private key
    -----\ n "atindex:0];
    
    
    [Rsa_private_key appendstring:@ \ \-----End RSA private key-----\ n];
    BIO *bio = NULL;
    const char * chprivatekey =[rsa_private_key utf8string];
    if (bio = Bio_new_mem_buf (Chprivatekey,-1) = = NULL)/Read the RSA public key {return nil from the string;
    
    RSA *rsa=pem_read_bio_rsaprivatekey (bio, NULL, NULL, NULL);
    
return RSA;
    #pragma mark-public key plus decryption//Fragment encryption + (NSData *) EncryptData: (NSData *) data withpublicrsa: (RSA *) publicrsa{//Get public key
    if (!PUBLICRSA) {return nil;          int publicrsalength = rsa_size (PUBLICRSA);                 Public key length Double totallength = [data length];                Total data length int blockSize = publicRSALength-12;     Data fragment size int blockcount = Ceil (totallength/blocksize);
Number of segments size_t publicencryptsize = Publicrsalength;    Nsmutabledata *encryptdate = [Nsmutabledata data];
        for (int i = 0; i < Blockcount i++) {Nsuinteger loc = i * blockSize;
        int datasegmentrealsize = MIN (blockSize, Totallength-loc);
        NSData *datasegment = [Data Subdatawithrange:nsmakerange (Loc, datasegmentrealsize)];
        Char *publicencrypt = malloc (publicrsalength);
        memset (publicencrypt, 0, publicrsalength);
        Const unsigned char *str = [datasegment bytes]; if (Rsa_public_encrypt (blocksize,str, unsigned char*) publicencrypt,publicrsa,rsa_pkcs1_padding) >=0) {NSData
            *encryptdata = [[NSData alloc] Initwithbytes:publicencrypt length:publicencryptsize];
        [Encryptdate Appenddata:encryptdata];
    Free (publicencrypt);
    
    } rsa_free (PUBLICRSA);
return encryptdate; //Fragment decryption + (NSData *) Decryptdata: (NSData *) data withpublicrsa: (RSA *) publicrsa{if (!publicrsa) {RET
    Urn Nil; int publicrsalength = RSA_size (PUBLICRSA);
    Double totallength = [data length];
    int blockSize = Publicrsalength;
    int blockcount = Ceil (totallength/blocksize);
    Nsmutabledata *decrypedata = [Nsmutabledata data];
        for (int i = 0; i < Blockcount i++) {Nsuinteger loc = i * blockSize;
        Long datasegmentrealsize = MIN (blockSize, Totallength-loc);
        NSData *datasegment = [Data Subdatawithrange:nsmakerange (Loc, datasegmentrealsize)];
        Const unsigned char *str = [datasegment bytes];
        unsigned char *privatedecrypt = malloc (publicrsalength);
        memset (privatedecrypt, 0, publicrsalength);  if (Rsa_public_decrypt (publicrsalength,str,privatedecrypt,publicrsa,rsa_pkcs1_padding) >=0) {NSInteger length
            =strlen ((char *) privatedecrypt);
            NSData *data = [[NSData alloc] Initwithbytes:privatedecrypt length:length];
        [Decrypedata Appenddata:data];
    Free (privatedecrypt);
    
} rsa_free (PUBLICRSA);    return decrypedata; #pragma encryption + (NSString *) encryptstring: (NSString *) content Withpublickey: (NSString *) publickey{//Encryption RS
    
    A *publicrsa=[self Creatersakeywithpublickey:publickey];
    
    NSData *data=[self encryptdata:[content datausingencoding:nsutf8stringencoding] WithPublicRSA:publicRSA];
    NSData *encodedata=[gtmbase64 Encodedata:data];
    
    NSData * Encodedata = [data base64encodeddatawithoptions:0];
    
    NSString * encrypotoresult= [[NSString alloc] Initwithdata:encodedata encoding:nsutf8stringencoding];
return encrypotoresult;
    
     #pragma decrypt + (NSString *) decryptstring: (NSString *) encryptcontent Withpublickey: (NSString *) publickey{//decryption
    
    RSA *publicrsa=[self Creatersakeywithpublickey:publickey];
     NSData *encodedata=[gtmbase64 Decodestring:encryptcontent]; NSData *encodedata = [[NSData alloc] initwithbase64encodedstring:encryptcontent options:
    
    Nsdatabase64decodingignoreunknowncharacters]; NSData *datA=[self Decryptdata:encodedata Withpublicrsa:publicrsa];
    
    NSString * decrypotoresult= [[NSString alloc] Initwithdata:data encoding:nsutf8stringencoding];
return decrypotoresult; #pragma mark-private key plus decryption//private key encryption + (NSData *) Encryptdate: (NSData *) data withprivatersa: (RSA *) privatersa{if (!PR
    IVATERSA) {return nil;          int privatersalength = rsa_size (PRIVATERSA);                 Public key length Double totallength = [data length];                Total data length int blockSize = privateRSALength-12;     Data fragment size int blockcount = Ceil (totallength/blocksize);
    Number of segments size_t privateencryptsize = Privatersalength;
    Nsmutabledata *encryptdate = [Nsmutabledata data];
        for (int i = 0; i < Blockcount i++) {Nsuinteger loc = i * blockSize;
        int datasegmentrealsize = MIN (blockSize, Totallength-loc);
        NSData *datasegment = [Data Subdatawithrange:nsmakerange (Loc, datasegmentrealsize)]; Char *publicencrypt = malloc (PRivatersalength);
        memset (publicencrypt, 0, privatersalength);
        Const unsigned char *str = [datasegment bytes]; if (Rsa_private_encrypt (datasegmentrealsize,str, unsigned char*) publicencrypt,privatersa,rsa_pkcs1_padding) >=
            0) {NSData *encryptdata = [[NSData alloc] Initwithbytes:publicencrypt length:privateencryptsize];
        [Encryptdate Appenddata:encryptdata];
    Free (publicencrypt);
    } rsa_free (PRIVATERSA);
return encryptdate; }//private key decryption + (NSData *) Decryptdata: (NSData *) data withprivatersa: (RSA *) Privatersa {if (!privatersa) {RE
    Turn nil;
    int privatersalenght = rsa_size (PRIVATERSA);
    Double totallength = [data length];
    int blockSize = Privatersalenght;
    int blockcount = Ceil (totallength/blocksize);
    Nsmutabledata *decrypedata = [Nsmutabledata data];
        for (int i = 0; i < Blockcount i++) {Nsuinteger loc = i * blockSize; Long datasegmentrealsize = MIN (BlockSize, Totallength-loc);
        NSData *datasegment = [Data Subdatawithrange:nsmakerange (Loc, datasegmentrealsize)];
        Const unsigned char *str = [datasegment bytes];
        unsigned char *privatedecrypt = malloc (privatersalenght);
        memset (privatedecrypt, 0, privatersalenght); if (Rsa_private_decrypt (privatersalenght,str,privatedecrypt,privatersa,rsa_pkcs1_padding) >=0) {NSInteger len
            Gth =strlen ((char *) privatedecrypt);
            NSData *data = [[NSData alloc] Initwithbytes:privatedecrypt length:length];
            
        [Decrypedata Appenddata:data];
    Free (privatedecrypt);
    } rsa_free (PRIVATERSA);
return decrypedata;
    
    #pragma encryption + (NSString *) encryptstring: (NSString *) content Withprivatekey: (NSString *) privatekey{//encryption
    
    RSA *privatersa=[self Creatersakeywithprivatekey:privatekey]; NSData *data=[self encryptdate:[content datausingencoding:nsutf8stringencoding] WithPrivateRSA:p Rivatersa];
    NSData *encodedata=[gtmbase64 Encodedata:data];
    NSData * Encodedata = [data base64encodeddatawithoptions:0];
    
    NSString * encrypotoresult= [[NSString alloc] Initwithdata:encodedata encoding:nsutf8stringencoding];
return encrypotoresult;
    
      #pragma decrypt + (NSString *) decryptstring: (NSString *) encryptcontent Withprivatekey: (NSString *) privatekey{//decryption
    
    RSA *privatersa=[self Creatersakeywithprivatekey:privatekey];
    can use the system base64, can also use GTMBase64 this library//nsdata *encodedata=[gtmbase64 decodestring:encryptcontent]; NSData *encodedata = [[NSData alloc] initwithbase64encodedstring:encryptcontent options:
    
    Nsdatabase64decodingignoreunknowncharacters];
    NSData *data=[self Decryptdata:encodedata Withprivatersa:privatersa];
    
    NSString * decrypotoresult= [[NSString alloc] Initwithdata:data encoding:nsutf8stringencoding];
return decrypotoresult;
 } @end




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.