RSA encryption _android for Android data encryption

Source: Internet
Author: User
Tags decrypt md5 encryption asymmetric encryption

Objective:

Recently accidentally and colleagues to exchange data security transmission problems, think of their own used RSA asymmetric encryption algorithm, idle down to sum up.

Several other encryption methods:

RSA encryption of Android data encryption
AES encryption of Android data encryption
Des encryption of Android data encryption
MD5 encryption of Android data encryption
BASE64 coding algorithm of Android data encryption
The safe hashing algorithm of SHA for android Data encryption

What is RSA encryption?

RSA algorithm is the most popular public key cryptography algorithm, using the length can change the key. RSA is the first algorithm that can be used both for data encryption and for digital signatures.

The principle of RSA algorithm is as follows:

1. Randomly selects two big prime numbers p and q,p not equal to Q, calculates N=PQ;
2. Select a natural number greater than 1 less than n e,e must be with (p-1) (q-1) the mutual element.
3. Use the formula to calculate D:DXE = 1 (mod (p-1) (q-1)).
4. Destroy P and Q.

The resulting N and E is the "public key", D is the "private key", the sender uses N to encrypt the data, and the receiver only uses D to unlock the data content.

RSA security relies on a large number of decomposition, n less than 1024 bits has proven to be unsafe, and since the RSA algorithm is based on a large number of computations, making RSA as fast as possible more than DES, which is the biggest drawback of RSA, it is usually only used to encrypt small amounts of data or cryptographic keys. But RSA is still a high strength algorithm.

How to use it?

The first step: to generate the secret key pair first

 /**
  * Randomly generated RSA key pair
  *
  * @param keylength key length, Range: 512~2048
  *     General 1024
  * @return
 /Public static KeyPair generatersakeypair (int keylength) {
  try {
   keypairgenerator KPG = keypairgenerator.getinstance ( RSA);
   Kpg.initialize (keylength);
   return Kpg.genkeypair ();
  } catch (NoSuchAlgorithmException e) {
   e.printstacktrace ();
   return null;
  }
 }

Specific encryption implementation:

Public Key Cryptography

 /**
  * Encrypt the string with public key
  * *
  @param data Original * *
 byte[static Encryptbypublickey (byte[) data, byte[] PublicKey) throws Exception {
  //Get public key
  x509encodedkeyspec keyspec = new X509encodedkeyspec (publickey);
  Keyfactory KF = Keyfactory.getinstance (RSA);
  PublicKey keypublic = Kf.generatepublic (keyspec);
  Encrypted data
  Cipher CP = Cipher.getinstance (ecb_pkcs1_padding);
  Cp.init (Cipher.encrypt_mode, keypublic);
  return cp.dofinal (data);
 }

Private key encryption

 /**
  * Private key encryption * @param data to be
  encrypted *
  @param privatekey Key
  * @return byte[] Encrypted data
 /Public Static byte[] Encryptbyprivatekey (byte[] data, byte[] privatekey) throws Exception {
  //Get private key
  Pkcs8encodedkeyspec Keyspec = new Pkcs8encodedkeyspec (privatekey);
  Keyfactory KF = Keyfactory.getinstance (RSA);
  Privatekey keyprivate = kf.generateprivate (keyspec);
  Data encryption
  Cipher Cipher = cipher.getinstance (ecb_pkcs1_padding);
  Cipher.init (Cipher.encrypt_mode, keyprivate);
  return cipher.dofinal (data);
 }

Public Key Decryption

 /**
  * Public Key decryption * * @param data to be  decrypted
  * @param publickey key
  * @return byte[] Decrypt data
 Static byte[] Decryptbypublickey (byte[] data, byte[] publickey) throws Exception {
  //Get public key
  X509encodedkeyspec Keyspec = new X509encodedkeyspec (publickey);
  Keyfactory KF = Keyfactory.getinstance (RSA);
  PublicKey keypublic = Kf.generatepublic (keyspec);
  Data decryption
  Cipher Cipher = cipher.getinstance (ecb_pkcs1_padding);
  Cipher.init (Cipher.decrypt_mode, keypublic);
  return cipher.dofinal (data);
 }

Private key decryption

 /**
  * Using the private key for decryption
 /public static byte[] Decryptbyprivatekey (byte[] encrypted, byte[] privatekey) throws Exception {
  //Get private key
  pkcs8encodedkeyspec keyspec = new Pkcs8encodedkeyspec (privatekey);
  Keyfactory KF = Keyfactory.getinstance (RSA);
  Privatekey keyprivate = kf.generateprivate (keyspec);

  Decrypt data
  Cipher CP = Cipher.getinstance (ecb_pkcs1_padding);
  Cp.init (Cipher.decrypt_mode, keyprivate);
  byte[] arr = cp.dofinal (encrypted);
  return arr;
 }

Several global variable explanations:

 public static final String RSA = "RSA";//Asymmetric Encryption key algorithm public
 static final string ecb_pkcs1_padding = "Rsa/ecb/pkcs1paddi Ng "//Encryption fill mode public
 static final int default_key_size = 2048;//secret key default length public
 static final byte[] Default_split =" #PART # ". GetBytes ();  When the content to be encrypted exceeds buffersize, Partsplit is used to block the encryption public
 static final int default_buffersize = (DEFAULT_KEY_SIZE/8)-11;// The current secret key supports the maximum number of bytes encrypted

About the encryption fill: Previously thought that these operations will be able to achieve RSA encryption and decryption, thought everything was all right, hehe, this thing is not finished, tragedy or happened, Android here encrypted data, the server end of the decryption, the original Android system RSA implementation is "rsa/none/ Nopadding "While the standard JDK implementation is" rsa/none/pkcs1padding ", which causes the inability to decrypt on the server after encryption on the Android computer, this must be noted when implemented.

Implementation of the segmented encryption: After the filling method and confident that all is well, but the accident or happened, RSA asymmetric encryption content length limit, 1024-bit key can only encrypt 127-bit data, otherwise it will be an error ( Javax.crypto.IllegalBlockSizeException:Data must is longer than 117 bytes), RSA is a commonly used asymmetric encryption algorithm. There was an "incorrect length" exception during the recent use, which was found to be caused by an unusually long amount of data to be encrypted. The RSA algorithm stipulates that the number of bytes to be encrypted cannot exceed the length of the key by 8 minus 11 (that is, KEYSIZE/8-11), and the number of bytes encrypted with the cipher is exactly the length of the key divided by 8 (that is, KEYSIZE/8).

Public-Key fragment encryption

/** * Use public key to segment the string (* * * * * * * byte[) encryptbypublickeyforspilt (byte[] data, byte[] publickey) throws exc
  eption {int datalen = data.length;
  if (Datalen <= default_buffersize) {return Encryptbypublickey (data, PublicKey);
  } list<byte> allbytes = new arraylist<byte> (2048);
  int bufindex = 0;
  int subdataloop = 0;
  byte[] buf = new Byte[default_buffersize];
   for (int i = 0; i < Datalen i++) {Buf[bufindex] = Data[i];
    if (++bufindex = = Default_buffersize | | | i = = dataLen-1) {subdataloop++;
     if (Subdataloop!= 1) {for (byte b:default_split) {Allbytes.add (b);
    } byte[] Encryptbytes = Encryptbypublickey (buf, PublicKey);
    for (byte b:encryptbytes) {Allbytes.add (b);
    } bufindex = 0;
    if (i = = dataLen-1) {buf = null;
    else {buf = new Byte[math.min (default_buffersize, Datalen-i-1)];
  }} byte[] bytes = new byte[allbytes.size ()];
{int i = 0;   for (Byte b:allbytes) {bytes[i++] = B.bytevalue ();
 } return bytes;

 }

private key fragment encryption  

 /** * @param data to encrypt the raw data * @param privatekey secret key/public static byte[] Encryptbyprivatekeyforspi
  LT (byte[] data, byte[] privatekey) throws Exception {int datalen = data.length;
  if (Datalen <= default_buffersize) {return Encryptbyprivatekey (data, Privatekey);
  } list<byte> allbytes = new arraylist<byte> (2048);
  int bufindex = 0;
  int subdataloop = 0;
  byte[] buf = new Byte[default_buffersize];
   for (int i = 0; i < Datalen i++) {Buf[bufindex] = Data[i];
    if (++bufindex = = Default_buffersize | | | i = = dataLen-1) {subdataloop++;
     if (Subdataloop!= 1) {for (byte b:default_split) {Allbytes.add (b);
    } byte[] Encryptbytes = Encryptbyprivatekey (buf, Privatekey);
    for (byte b:encryptbytes) {Allbytes.add (b);
    } bufindex = 0;
    if (i = = dataLen-1) {buf = null;
    else {buf = new Byte[math.min (default_buffersize, Datalen-i-1)]; }} byte[] Bytes = new byte[allbytes.size ()];
   {int i = 0;
   for (Byte b:allbytes) {bytes[i++] = B.bytevalue ();
 } return bytes;

 }

Public key fragment decryption  

 /** * Public Key Fragment decryption * * @param encrypted data to be decrypted * @param publickey Key * * * * byte[] Decryptbypublickeyforsp
  ILT (byte[] encrypted, byte[] publickey) throws Exception {int splitlen = default_split.length;
  if (Splitlen <= 0) {return Decryptbypublickey (encrypted, publickey);
  int datalen = Encrypted.length;
  list<byte> allbytes = new arraylist<byte> (1024);
  int lateststartindex = 0;
   for (int i = 0; i < Datalen i++) {byte BT = encrypted[i];
   Boolean ismatchsplit = false;
    if (i = = dataLen-1) {//to the last byte[of data] part = new Byte[datalen-lateststartindex];
    System.arraycopy (Encrypted, Lateststartindex, part, 0, part.length);
    byte[] Decryptpart = Decryptbypublickey (part, PublicKey);
    for (byte B:decryptpart) {Allbytes.add (b);
    } Lateststartindex = i + Splitlen;
   i = latestStartIndex-1; else if (BT = = Default_split[0]) {//This is split[0] opening if (Splitlen > 1) {if (i + splitleN < Datalen) {//no out-of-scope for (int j = 1; j < Splitlen; J +) {if (Default_split[j]!= Encryp
       Ted[i + j]) {break;
       } if (j = = splitLen-1) {//verify to the last of the split, there is no break, it indicates that the split segment Ismatchsplit = True is confirmed;
    else {//split is only one bit, and has already matched ismatchsplit = true;
    } if (Ismatchsplit) {byte[] part = new Byte[i-lateststartindex];
    System.arraycopy (Encrypted, Lateststartindex, part, 0, part.length);
    byte[] Decryptpart = Decryptbypublickey (part, PublicKey);
    for (byte B:decryptpart) {Allbytes.add (b);
    } Lateststartindex = i + Splitlen;
   i = latestStartIndex-1;
  } byte[] bytes = new byte[allbytes.size ()];
   {int i = 0;
   for (Byte b:allbytes) {bytes[i++] = B.bytevalue ();
 } return bytes;

 }

private key fragment decryption  

 /** * Using private key to decrypt */public static byte[] Decryptbyprivatekeyforspilt (byte[] encrypted, byte[] privatekey) throws
  Exception {int splitlen = default_split.length;
  if (Splitlen <= 0) {return Decryptbyprivatekey (encrypted, privatekey);
  int datalen = Encrypted.length;
  list<byte> allbytes = new arraylist<byte> (1024);
  int lateststartindex = 0;
   for (int i = 0; i < Datalen i++) {byte BT = encrypted[i];
   Boolean ismatchsplit = false;
    if (i = = dataLen-1) {//to the last byte[of data] part = new Byte[datalen-lateststartindex];
    System.arraycopy (Encrypted, Lateststartindex, part, 0, part.length);
    byte[] Decryptpart = Decryptbyprivatekey (part, Privatekey);
    for (byte B:decryptpart) {Allbytes.add (b);
    } Lateststartindex = i + Splitlen;
   i = latestStartIndex-1; else if (BT = = Default_split[0]) {//This is split[0] opening if (Splitlen > 1) {if (i + Splitlen < Datalen)
    {//No more than the data range  for (int j = 1; j < Splitlen; J +) {if (Default_split[j]!= encrypted[i + j]) {break;
       } if (j = = splitLen-1) {//verify to the last of the split, there is no break, it indicates that the split segment Ismatchsplit = True is confirmed;
    else {//split is only one bit, and has already matched ismatchsplit = true;
    } if (Ismatchsplit) {byte[] part = new Byte[i-lateststartindex];
    System.arraycopy (Encrypted, Lateststartindex, part, 0, part.length);
    byte[] Decryptpart = Decryptbyprivatekey (part, Privatekey);
    for (byte B:decryptpart) {Allbytes.add (b);
    } Lateststartindex = i + Splitlen;
   i = latestStartIndex-1;
  } byte[] bytes = new byte[allbytes.size ()];
   {int i = 0;
   for (Byte b:allbytes) {bytes[i++] = B.bytevalue ();
 } return bytes;

 }

This finally solves the problem that meets, the project uses is the client public key encryption, the server private key decrypts, the server developer says is for the efficiency consideration, therefore still wrote a program to test the real efficiency

Step One: prepare 100 Object data

  List<person> personlist=new arraylist<> ();
  The maximum number of data bars for int testmaxcount=100;//test
  //Add test data for
  (int i=0;i<testmaxcount;i++) {person person
   =new person ();
   Person.setage (i);
   Person.setname (string.valueof (i));
   Personlist.add (person);
  }
  Fastjson generates JSON data

  String Jsondata=jsonutils.objecttojsonforfastjson (personlist);

  LOG.E ("Mainactivity", "pre-encrypted JSON data---->" +jsondata);
  LOG.E ("Mainactivity", "encrypt front json data length---->" +jsondata.length ());

Step Two: generate a secret key pair

  KeyPair Keypair=rsautils.generatersakeypair (rsautils.default_key_size);
  Public key
  Rsapublickey PublicKey = (rsapublickey) keypair.getpublic ();
  Private key
  Rsaprivatekey Privatekey = (rsaprivatekey) keypair.getprivate (); 

Next use public key encryption private key to decrypt private key encryption public key decryption

  Public key encryption Long Start=system.currenttimemillis ();
  Byte[] encryptbytes= rsautils.encryptbypublickeyforspilt (Jsondata.getbytes (), publickey.getencoded ());
  Long End=system.currenttimemillis ();
  LOG.E ("Mainactivity", "public key encryption time-consuming cost time---->" + (End-start));
  String Encrystr=base64encoder.encode (encryptbytes);
  LOG.E ("Mainactivity", "encrypted JSON data--1-->" +ENCRYSTR);
  LOG.E ("Mainactivity", "encrypted JSON data length--1-->" +encrystr.length ());
  Private key decryption Start=system.currenttimemillis (); Byte[] decryptbytes= rsautils.decryptbyprivatekeyforspilt (base64decoder.decodetobytes (ENCRYSTR),
  Privatekey.getencoded ());
  String Decrystr=new string (decryptbytes);
  End=system.currenttimemillis ();
  LOG.E ("Mainactivity", "private key decryption time-consuming cost time---->" + (End-start));

  LOG.E ("Mainactivity", "decrypted JSON data--1-->" +DECRYSTR);
  Private key encryption Start=system.currenttimemillis ();
  Encryptbytes= rsautils.encryptbyprivatekeyforspilt (Jsondata.getbytes (), privatekey.getencoded ());
  End=system.currenttimemillis (); LOG.E ("MainactiviTy "," private key encryption time-consuming cost time----> "+ (End-start));
  Encrystr=base64encoder.encode (encryptbytes);
  LOG.E ("Mainactivity", "encrypted JSON data--2-->" +ENCRYSTR);
  LOG.E ("Mainactivity", "encrypted JSON data length--2-->" +encrystr.length ());
  Public key decryption Start=system.currenttimemillis (); Decryptbytes= rsautils.decryptbypublickeyforspilt (Base64decoder.decodetobytes (ENCRYSTR), publicKey.getEncoded ())
  ;
  Decrystr=new String (decryptbytes);
  End=system.currenttimemillis ();
  LOG.E ("Mainactivity", "public key decryption time-consuming cost time---->" + (End-start));

 LOG.E ("Mainactivity", "decrypted JSON data--2-->" +DECRYSTR);

Run Result:

Comparison found that the encryption of the private key is time-consuming, so can be based on different requirements of the solution to add and decrypt. Personally feel that the server requires high decryption efficiency, the client key encryption, the server public key decryption is better

Data size changes after encryption: The amount of data is almost 1.5 times times before the encryption

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.