An explanation of RSA encryption and SHA signature usage

Source: Internet
Author: User
Tags min modulus openssl openssl rsa openssl x509 asymmetric encryption
Basic Knowledge


what is RSA.
A: RSA is an asymmetric encryption algorithm, often used to encrypt the transmitted data, with the Digital Digest algorithm, you can also be text signature.



padding in RSA encryption.
A: Padding is the Fill method, because the RSA encryption algorithm to encrypt the clear text is smaller than the modulus, padding is through some fill way to limit the length of the plaintext. Several modes of padding and segmented encryption are described in detail later.



What is the difference between encryption and sign-up?
A: The public key is placed on the client, and the data is encrypted with the public key, and the server is decrypted with the private key after it gets the data;
Add-on: The private key is placed on the client, and the data is signed with the private key, the service side to get the data with the public key for verification.
The former is purely for encryption, the latter is mainly for the purpose of preventing malicious attacks, to prevent others from impersonating our client to attack our server, causing the server to crash.

 Fundamentals



RSA encrypts the data using a key pair, which needs to survive the public key and the private key before encryption and decryption.
Public key: Used to encrypt data. Used for public, typically stored in data providers, such as iOS clients.
Private key: Used to decrypt data. Must be kept secret and private key leaks can create security issues.
The Security.framework in iOS provides support for the RSA algorithm, which requires processing the key pair, generating a certificate from public key, and generating a key in the P12 format with private key. Think of the Jave directly with string encryption and decryption is much simpler. (⊙o⊙) ...

actual Combat



Certificate Generation
RSA encrypts this public key, the private key is necessary. Apple does not support encrypting and decrypting directly using strings, it is recommended to use the P12 file. Here we go. Generate all the files used in encryption and provide it to Java.


 -Generate a private key with a modulus length of 1024bit
   OpenSSL genrsa-out private_key.pem

 -Generate certification require file
   OpenSSL req-new-k EY private_key.pem-out RSACERTREQ.CSR

 -Generate certification and specify expiration time
   OpenSSL x509-req-days 3650-in RSACERTREQ.CSR- Signkey private_key.pem-out RSACERT.CRT

 -Generate public key for iOS to use
   OpenSSL x509-outform der-in rsacert.crt-out public_key.d ER

 -Generate private key for iOS use this way will let you enter the password, later used in the generation of SECKEYREF will use this password
   OpenSSL pkcs12-export-out private_key.p12-inkey Private_key.pem-in RSACERT.CRT

 -Generate the public key at the end of the PEM for use with
   OpenSSL rsa-in private_key.pem-out Rsa_public_key.pem for Java- Pubout

 -Generate the private key at the end of the PEM for use with the
   OpenSSL pkcs8-topk8-in private_key.pem-out in Java pkcs8_private_key.pem-nocrypt
generate seckeyref for public and private keys
//generate the private key corresponding to your P12 file the Seckeyref side returns if nil please check your P12 file generation steps-(SECKEYREF)
Getprivatekeyrefrencefromdata: (nsdata*) p12data password: (nsstring*) Password {seckeyref privatekeyref = NULL;
nsmutabledictionary * options = [[Nsmutabledictionary alloc] init];
[Options Setobject:password Forkey: (__bridge ID) ksecimportexportpassphrase];
Cfarrayref items = cfarraycreate (null, 0, 0, NULL);
Osstatus Securityerror = Secpkcs12import ((__bridge cfdataref) P12data, (__bridge cfdictionaryref) options, &items); if (Securityerror = = NoErr && cfarraygetcount (items) > 0) {cfdictionaryref identitydict = Cfarraygetvaluea
    Tindex (items, 0);
    Secidentityref Identityapp = (secidentityref) cfdictionarygetvalue (identitydict, ksecimportitemidentity);
    Securityerror = Secidentitycopyprivatekey (Identityapp, &privatekeyref);
    if (securityerror! = noErr) {privatekeyref = NULL;

}} cfrelease (items);
return privatekeyref; }
According to your der file public key corresponds to Seckeyref
 -(seckeyref) Getpublickeyrefrencefromedata:    (nsdata*) derdata {

Seccertificateref mycertificate = Seccertificatecreatewithdata (Kcfallocatordefault, (__bridge CFDataRef) derData);
Secpolicyref MyPolicy = SecPolicyCreateBasicX509 ();
Sectrustref Mytrust;
Osstatus status = Sectrustcreatewithcertificates (Mycertificate,mypolicy,&mytrust);
Sectrustresulttype Trustresult;
if (status = = NOERR) {
    status = Sectrustevaluate (Mytrust, &trustresult);
}
Seckeyref SecurityKey = Sectrustcopypublickey (mytrust);
Cfrelease (mycertificate);
Cfrelease (mypolicy);
Cfrelease (mytrust);

return securitykey;
}
Encryption and decryption
-(nsdata*) Rsaencryptdata: (nsdata*) data {seckeyref key = [self getpublickey];
    size_t cipherbuffersize = seckeygetblocksize (key);
    uint8_t *cipherbuffer = malloc (cipherbuffersize * sizeof (uint8_t));
      size_t blockSize = cipherBufferSize-11;
      size_t Blockcount = (size_t) ceil ([Data length]/(double) blockSize);
    Nsmutabledata *encrypteddata = [[Nsmutabledata alloc] init];
    for (int i=0; i<blockcount; i++) {unsigned long buffersize = MIN (blockSize, [data length]-I * blockSize);
    NSData *buffer = [Data Subdatawithrange:nsmakerange (i * blockSize, buffersize)]; Osstatus status = Seckeyencrypt (Key, kSecPaddingPKCS1, (const uint8_t *) [buffer bytes], [buffer length], Cipherbuffer, &am

    P;cipherbuffersize);
    if (Status! = NOERR) {return nil;
    } nsdata *encryptedbytes = [[NSData alloc] initwithbytes: (const void *) Cipherbuffer length:cipherbuffersize];
    [EncryptedData appenddata:encryptedbytes]; } if (Cipherbuffer) {freE (Cipherbuffer);
  } return EncryptedData; }
-(nsdata*) Rsadecryptdata: (nsdata*) data {seckeyref key = [self getprivatkey];
size_t cipherbuffersize = seckeygetblocksize (key);
size_t blockSize = cipherbuffersize;

size_t Blockcount = (size_t) ceil ([Data length]/(double) blockSize);

Nsmutabledata *decrypteddata = [[Nsmutabledata alloc] init];
    for (int i = 0; i < Blockcount; i++) {unsigned long buffersize = MIN (blockSize, [data length]-I * blockSize);

    NSData *buffer = [Data Subdatawithrange:nsmakerange (i * blockSize, buffersize)];
    size_t Cipherlen = [buffer length];
    void *cipher = malloc (Cipherlen);
    [Buffer getbytes:cipher Length:cipherlen];
    size_t Plainlen = seckeygetblocksize (key);

    void *plain = malloc (Plainlen);

    Osstatus status = Seckeydecrypt (key, kSecPaddingPKCS1, cipher, Cipherlen, Plain, &plainlen);
    if (Status! = NOERR) {return nil;
    } nsdata *decryptedbytes = [[NSData alloc] initwithbytes: (const void *) plain length:plainlen]; [Decrypteddata Appenddata:dEcryptedbytes];
} return decrypteddata; }
padding in RSA encryption


Rsa_pkcs1_padding fill mode, the most commonly used mode
Requirements: Input: must be shorter than RSA key modulo length (modulus) at least 11 bytes, that is, Rsa_size (RSA) –11 If the input clear text is too long, you must cut and then fill.
Output: As long as modulus
According to this requirement, for a 1024bit key, block length = 1024/8–11 = 117 bytes



Rsa_pkcs1_oaep_padding
Input: Rsa_size (RSA) –41
Output: As long as modulus



Rsa_no_padding not populated
Input: Can be as long as the RSA key modulus, if the input clear text is too long, you must cut, and then fill
Output: as long as modulus

signature and verification 


//data sha256 Signature-(NSData *) Rsasha256signdata: (NSData *) plaindata {seckeyref key = [self get

  Privatkey];
  size_t signedhashbytessize = seckeygetblocksize (key);
  uint8_t* signedhashbytes = malloc (signedhashbytessize);

  memset (Signedhashbytes, 0x0, signedhashbytessize);
  size_t hashbytessize = cc_sha256_digest_length;
  uint8_t* hashbytes = malloc (hashbytessize); if (!

       cc_sha256 ([plaindata bytes], (cc_long) [Plaindata length], hashbytes) {return nil;}
              Seckeyrawsign (Key, ksecpaddingpkcs1sha256, Hashbytes, Hashbytessize,

    Signedhashbytes, &signedhashbytessize); nsdata* Signedhash = [NSData datawithbytes:signedhashbytes length: (Nsuinteger) Signedha

    Shbytessize];
    if (hashbytes) free (hashbytes);

    if (signedhashbytes) free (signedhashbytes);
    return signedhash; }
//this side of the signed data to verify successful verification, then return Yes-(BOOL) Rsasha256verifydata: (NSData *) Plaindata withsignature:

    (NSData *) Signature {seckeyref key = [self getpublickey];
    size_t signedhashbytessize = seckeygetblocksize (key);

    Const void* signedhashbytes = [signature bytes];
    size_t hashbytessize = cc_sha256_digest_length;
    uint8_t* hashbytes = malloc (hashbytessize); if (!
    cc_sha256 ([plaindata bytes], (cc_long) [Plaindata length], hashbytes)) {return NO;
                                  } osstatus status = Seckeyrawverify (key, ksecpaddingpkcs1sha256, Hashbytes, Hashbytessize, Signedhash

    Bytes, signedhashbytessize);
    return status = = Errsecsuccess; }

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.