-
-
Save awesometic/f1f52acf5904189f687724e42c461413 to your computer and use it in GitHub Desktop.
| /** | |
| * Created by Awesometic | |
| * It's encrypt returns Base64 encoded, and also decrypt for Base64 encoded cipher | |
| * references: http://stackoverflow.com/questions/12471999/rsa-encryption-decryption-in-android | |
| */ | |
| import android.util.Base64; | |
| import java.nio.charset.StandardCharsets; | |
| import java.security.InvalidKeyException; | |
| import java.security.KeyFactory; | |
| import java.security.KeyPair; | |
| import java.security.KeyPairGenerator; | |
| import java.security.NoSuchAlgorithmException; | |
| import java.security.PrivateKey; | |
| import java.security.PublicKey; | |
| import java.security.spec.InvalidKeySpecException; | |
| import java.security.spec.X509EncodedKeySpec; | |
| import javax.crypto.BadPaddingException; | |
| import javax.crypto.Cipher; | |
| import javax.crypto.IllegalBlockSizeException; | |
| import javax.crypto.NoSuchPaddingException; | |
| public class RSACipher { | |
| KeyPairGenerator kpg; | |
| KeyPair kp; | |
| PublicKey publicKey; | |
| PrivateKey privateKey; | |
| byte[] encryptedBytes, decryptedBytes; | |
| Cipher cipher, cipher1; | |
| String encrypted, decrypted; | |
| private final static String CRYPTO_METHOD = "RSA"; | |
| private final static int CRYPTO_BITS = 2048; | |
| public RSACipher() | |
| throws NoSuchAlgorithmException, | |
| NoSuchPaddingException, | |
| InvalidKeyException, | |
| IllegalBlockSizeException, | |
| BadPaddingException { | |
| generateKeyPair(); | |
| } | |
| private void generateKeyPair() | |
| throws NoSuchAlgorithmException, | |
| NoSuchPaddingException, | |
| InvalidKeyException, | |
| IllegalBlockSizeException, | |
| BadPaddingException { | |
| kpg = KeyPairGenerator.getInstance(CRYPTO_METHOD); | |
| kpg.initialize(CRYPTO_BITS); | |
| kp = kpg.genKeyPair(); | |
| publicKey = kp.getPublic(); | |
| privateKey = kp.getPrivate(); | |
| } | |
| /** | |
| * Encrypt plain text to RSA encrypted and Base64 encoded string | |
| * | |
| * @param args | |
| * args[0] should be plain text that will be encrypted | |
| * If args[1] is be, it should be RSA public key to be used as encrypt public key | |
| * @return a encrypted string that Base64 encoded | |
| * @throws NoSuchAlgorithmException | |
| * @throws NoSuchPaddingException | |
| * @throws InvalidKeyException | |
| * @throws IllegalBlockSizeException | |
| * @throws BadPaddingException | |
| */ | |
| public String encrypt(Object... args) | |
| throws NoSuchAlgorithmException, | |
| NoSuchPaddingException, | |
| InvalidKeyException, | |
| IllegalBlockSizeException, | |
| BadPaddingException { | |
| String plain = (String) args[0]; | |
| PublicKey rsaPublicKey; | |
| if (args.length == 1) { | |
| rsaPublicKey = this.publicKey; | |
| } else { | |
| rsaPublicKey = (PublicKey) args[1]; | |
| } | |
| cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); | |
| cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); | |
| encryptedBytes = cipher.doFinal(plain.getBytes(StandardCharsets.UTF_8)); | |
| return Base64.encodeToString(encryptedBytes, Base64.DEFAULT); | |
| } | |
| public String decrypt(String result) | |
| throws NoSuchAlgorithmException, | |
| NoSuchPaddingException, | |
| InvalidKeyException, | |
| IllegalBlockSizeException, | |
| BadPaddingException { | |
| cipher1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); | |
| cipher1.init(Cipher.DECRYPT_MODE, privateKey); | |
| decryptedBytes = cipher1.doFinal(Base64.decode(result, Base64.DEFAULT)); | |
| decrypted = new String(decryptedBytes); | |
| return decrypted; | |
| } | |
| public String getPublicKey(String option) | |
| throws NoSuchAlgorithmException, | |
| NoSuchPaddingException, | |
| InvalidKeyException, | |
| IllegalBlockSizeException, | |
| BadPaddingException { | |
| switch (option) { | |
| case "pkcs1-pem": | |
| String pkcs1pem = "-----BEGIN RSA PUBLIC KEY-----\n"; | |
| pkcs1pem += Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT); | |
| pkcs1pem += "-----END RSA PUBLIC KEY-----"; | |
| return pkcs1pem; | |
| case "pkcs8-pem": | |
| String pkcs8pem = "-----BEGIN PUBLIC KEY-----\n"; | |
| pkcs8pem += Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT); | |
| pkcs8pem += "-----END PUBLIC KEY-----"; | |
| return pkcs8pem; | |
| case "base64": | |
| return Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT); | |
| default: | |
| return null; | |
| } | |
| } | |
| public static PublicKey stringToPublicKey(String publicKeyString) | |
| throws NoSuchAlgorithmException, | |
| NoSuchPaddingException, | |
| InvalidKeyException, | |
| IllegalBlockSizeException, | |
| BadPaddingException { | |
| try { | |
| if (publicKeyString.contains("-----BEGIN PUBLIC KEY-----") || publicKeyString.contains("-----END PUBLIC KEY-----")) | |
| publicKeyString = publicKeyString.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", ""); | |
| byte[] keyBytes = Base64.decode(publicKeyString, Base64.DEFAULT); | |
| X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); | |
| KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
| return keyFactory.generatePublic(spec); | |
| } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { | |
| e.printStackTrace(); | |
| return null; | |
| } | |
| } | |
| } |
when i run below :
String result = null;
String g = null;
try {
result = new Pgp().encrypt("slkdfjlks");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
try {
g = new Pgp().decrypt(result);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
i get this error :
javax.crypto.BadPaddingException: data hash wrong
and exception is because of this line in decrypt function
decryptedBytes = cipher1.doFinal(Base64.decode(result, Base64.DEFAULT));
public String decrypt(String result)
throws NoSuchAlgorithmException,
NoSuchPaddingException,
InvalidKeyException,
IllegalBlockSizeException,
BadPaddingException {
cipher1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
decryptedBytes = cipher1.doFinal(Base64.decode(result, Base64.DEFAULT));
decrypted = new String(decryptedBytes);
return decrypted;
}
when i run below :
String result = null; String g = null; try { result = new Pgp().encrypt("slkdfjlks"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } try { g = new Pgp().decrypt(result); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); }i get this error :
javax.crypto.BadPaddingException: data hash wrong
and exception is because of this line in decrypt function
decryptedBytes = cipher1.doFinal(Base64.decode(result, Base64.DEFAULT));public String decrypt(String result) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { cipher1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); cipher1.init(Cipher.DECRYPT_MODE, privateKey); decryptedBytes = cipher1.doFinal(Base64.decode(result, Base64.DEFAULT)); decrypted = new String(decryptedBytes); return decrypted; }
If you are using a hardcoded private string then you must check that
start/begin is same as pkcs8Pem = pkcs8Pem.replace("-----BEGIN PRIVATE KEY-----", "");
and end/completes with the pkcs8Pem = pkcs8Pem.replace("-----END PRIVATE KEY-----", "");
i get this error on decryption :
com.android.org.bouncycastle.jcajce.provider.util.BadBlockException: unable to decrypt block
at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.getOutput(CipherSpi.java:553)
at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(CipherSpi.java:498)
at javax.crypto.Cipher.doFinal(Cipher.java:2056)
at com.example.magicchatapp.utils.security.RSACipher.decrypt(RSACipher.java:106)
at com.example.magicchatapp.presentation.fragment.SingleChatThreadFragment
Excellent coding .
you can use below code for creating PRIVATE KEY from a string: