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.