RSA String Encryption, security
In this tutorial, I show you how to encrypt a string with public key in Android.
First we make a 2048-bit RSA private key in linux:
- $ openssl genrsa -out private_key.pem 2048
Then convert private Key to PKCS#8 format, what Java can read: (in Linux)
- $ openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt
Then output public key portion in DER format, what Java can read: (in Linux)
- $ openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
Now you have 3 files:
- private_key.pem (you can use this in php to decrypt)
- private_key.der (with this you can decrypt on Android)
- public_key.der (that key use we to encrypt now)
When you have the files, copy public_key.der to the root of your SD-card.
Let’s create encrypt method, that wait for the key path and the string to encode, and return String:
Next create PublicKey object from the public_key file:
- byte[] encodedKey = new byte[instream.available()];
- instream.read(encodedKey);
Now init chiper, than encrypt the string. Encrypted string in byte[]:
- Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING&quo
t;); - pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic);
- byte[] encryptedInByte = pkCipher.doFinal(original.getBytes());
Now create a new class next to the Main activity that called Base64Coder. It should look like:
- package your.package.name;
- public class Base64Coder {
- private static char[] map1 = new char[64];
- static {
- int i = 0;
- for (char c = 'A'; c <= 'Z'; c++)
- map1[i++] = c;
- for (char c = 'a'; c <= 'z'; c++)
- map1[i++] = c;
- for (char c = '0'; c <= '9'; c++)
- map1[i++] = c;
- map1[i++] = '+';
- map1[i++] = '/';
- }
- private static byte[] map2 = new byte[128];
- static {
- for (int i = 0; i < map2.length; i++)
- map2[i] = -1;
- for (int i = 0; i < 64; i++)
- map2[map1[i]] = (byte) i;
- }
- }
- public static char[] encode(byte[] in) {
- return encode(in, in.length);
- }
- public static char[] encode(byte[] in, int iLen) {
- int oDataLen = (iLen * 4 + 2) / 3;
- int oLen = ((iLen + 2) / 3) * 4;
- char[] out = new char[oLen];
- int ip = 0;
- int op = 0;
- while (ip < iLen) {
- int i0 = in[ip++] & 0xff;
- int i1 = ip < iLen ? in[ip++] & 0xff : 0;
- int i2 = ip < iLen ? in[ip++] & 0xff : 0;
- int o0 = i0 >>> 2;
- int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
- int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
- int o3 = i2 & 0x3F;
- out[op++] = map1[o0];
- out[op++] = map1[o1];
- out[op] = op < oDataLen ? map1[o2] : '=';
- op++;
- out[op] = op < oDataLen ? map1[o3] : '=';
- op++;
- }
- return out;
- }
- }
- return decode(s.toCharArray());
- }
- public static byte[] decode(char[] in) {
- int iLen = in.length;
- if (iLen % 4 != 0)
- "Length of Base64 encoded input string is not a multiple of 4.");
- while (iLen > 0 && in[iLen - 1] == '=')
- iLen--;
- int oLen = (iLen * 3) / 4;
- byte[] out = new byte[oLen];
- int ip = 0;
- int op = 0;
- while (ip < iLen) {
- int i0 = in[ip++];
- int i1 = in[ip++];
- int i2 = ip < iLen ? in[ip++] : 'A';
- int i3 = ip < iLen ? in[ip++] : 'A';
- if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
- "Illegal character in Base64 encoded data.");
- int b0 = map2[i0];
- int b1 = map2[i1];
- int b2 = map2[i2];
- int b3 = map2[i3];
- if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
- "Illegal character in Base64 encoded data.");
- int o0 = (b0 << 2) | (b1 >>> 4);
- int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
- int o2 = ((b2 & 3) << 6) | b3;
- out[op++] = (byte) o0;
- if (op < oLen)
- out[op++] = (byte) o1;
- if (op < oLen)
- out[op++] = (byte) o2;
- }
- return out;
- }
- private Base64Coder() {
- }
- }
Now you can convert the encoded byte[] to Base64. From the Base64 create String, and return it:
Also look like this:
- public String encrypt(String filePath, String original) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
- byte[] encodedKey = new byte[instream.available()];
- instream.read(encodedKey);
- Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING&quo
t;); - pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic);
- byte[] encryptedInByte = pkCipher.doFinal(original.getBytes());
- return encryptedInString;
- }
An example how to use this implemented method:
- encrypt("/sdcard/public_key.der&q
uot;,"text to encrypt");
For example: that encrypted string can you send to a web service, and decrypt with the private_key.pem in PHP
New tutorials from Helloandroid
Recent Apps
Android on Twitter
-
@Idevicegazette (iDevice Gazette)
GSM-to-Skype bridge lets you lose those roaming fees http://bit.ly/lbRJeh #android
12 years 3 weeks ago -
@tommy_banane (tom b.)
RT @AndroidFavorite: #Android New Desktop Android Market Is Live, Adds Several New Features http://zorr0.nl/lFwXNz
12 years 3 weeks ago -
@dwilliams5 (Dennis Williams)
just completed a runtastic run of 3.02 km in 40 min 11 s with #runtastic #Android App: http://tinyurl.com/5tvrpe3
12 years 3 weeks ago -
@S_Pinz (Spinz!)
RT @Androidheadline: Out of box #LG Optimus 3D got Quadrant 2420 score. Thanks @blink_c #io2011 #android http://twitpic.com/4whkdz
12 years 3 weeks ago -
@tayaitapps (Taya IT)
Next Google TV Looks A Lot Like Android http://t.co/dvlTim3 via @alleyinsider #google #apple #android #tv #honeycomb
12 years 3 weeks ago
Poll
Useful resources
Android Development Projects
- App Development
- Telegram bulk messages sender
- Photo Editing Application
- React Native Developer - part time basis
- Locket App Copy
- Courier app $150 only
- Mobile Application Development - IOS and Android (Rewards for sharing brand ads on social media)
- Android app for sms
- Fitness app project for sale online
- io developer