An article on RSA encryption and SHA Signature | fully synchronized with Java

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

See this article students can be happy, at that time in the RSA encryption and signature when the online information is simply not too old, after finishing it is unbearable, this article I will explain in detail iOS how to implement RSA encryption and signature, and full synchronization with Java, this is my second blog, If there are any shortcomings, please advise us.

Basic knowledge

    1. 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.

    2. RSA encryption in padding?

      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.

    3. What is the difference between encryption and signing?

      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.

Basic principle

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 to teach you to generate all the files used in the encryption, and provided to Java use, think of this public key private key for half a day. %>_

  • Generate a private key with a modulus length of 1024bit

    OpenSSL genrsa-out Private_key.pem 1024

  • Generate certification Require file

    OpenSSL Req-new-key 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 a public key for use with iOS

    OpenSSL x509-outform der-in rsacert.crt-out Public_key.der

  • Generate a private key for iOS use this way you will be prompted for a password, which will be used later when generating seckeyref.

    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 in Java

    OpenSSL rsa-in private_key.pem-out rsa_public_key.pem-pubout

  • Generate the private key at the end of the PEM for Java to use OpenSSL pkcs8-topk8-in private_key.pem-out pkcs8_private_key.pem-nocrypt

All of the above steps are done under the terminal Oh (^__^)

Generate Seckeyref for public and private keys

Generate the private key according to your p12 file the corresponding seckeyref this 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 = cfarraygetvalueatindex(items, 0 );

secidentityref Identityapp = (secidentityref)cfdictionarygetvalue( identitydict, ksecimportitemidentity);

securityerror = secidentitycopyprivatekey(identityapp, &privatekeyref);

if (securityerror! = noErr) {

privatekeyref = NULL;

}

}

Cfrelease(items);

return privatekeyref;

}

Based on the seckeyref of your der file's public key

- (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 - one;

size_t Blockcount = (size_t)ceil([data length] / ( Double)blockSize);

nsmutabledata *encrypteddata = [[nsmutabledata alloc] init];

for (int i=0; i

- (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

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

SHA256 Signature of data

- (nsdata *)rsasha256signdata:(nsdata *)plaindata {

seckeyref Key = [self getprivatkey];

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)signedhashbytessize];

if (hashbytes)

free(hashbytes);

if (signedhashbytes)

free(signedhashbytes);

return signedhash;

}

//This side verifies that the signed data is successful, then returns 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)) {< /c2>

return NO;

}

osstatus Status = seckeyrawverify(key,

ksecpaddingpkcs1sha256,

hashbytes,

hashbytessize,

signedhashbytes,

signedhashbytessize);

return status = = errsecsuccess;

}

This is the end of the article, I hope this article is helpful to everyone. To see the demo, click here: Xyrsacryptor

Https://github.com/panxianyue/RSACryptor.git

One piece of RSA encryption and SHA Signature | Fully synchronized with Java

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.