RSA Encryption Decryption in Android

前端 未结 5 948
时光取名叫无心
时光取名叫无心 2020-12-12 11:12

I am implementing a demo for RSA Encryption and Decryption in Android. I can Perform Encryption very well, but In Decryption I get an Exception: >>java.security.

相关标签:
5条回答
  • 2020-12-12 11:52

    when using RSAEcvypt method, its fill PublicKey and private key. And when your Decrypt your generated byte[], your publicKey and privateKey being NULL. Because of that you get this error.

    You should use your keys static;

    enter code here
    
    KeyPairGenerator kpg;
    KeyPair kp;
    static PublicKey publicKey;
    static PrivateKey privateKey;
    byte [] encryptedBytes,decryptedBytes;
    Cipher cipher,cipher1;
    String encrypted,decrypted;
    
    0 讨论(0)
  • 2020-12-12 11:54

    I think the problem is that you should use the same key pair to encrypt and decrypt the cipher. Referring to the JavaDoc:

     genKeyPair() This will generate a new key pair every time it is called.
    
    0 讨论(0)
  • 2020-12-12 11:55

    My class:

    package com.infovale.cripto;
    
    import java.io.UnsupportedEncodingException;
    import java.math.BigInteger;
    import java.security.InvalidKeyException;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.util.Arrays;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    
    public class RSA {
    
    KeyPairGenerator kpg;
    KeyPair kp;
    PublicKey publicKey;
    PrivateKey privateKey;
    byte[] encryptedBytes, decryptedBytes;
    Cipher cipher, cipher1;
    String encrypted, decrypted;
    
    public String Encrypt (String plain) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
    {
        kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        kp = kpg.genKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();
    
        cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        encryptedBytes = cipher.doFinal(plain.getBytes());
    
        encrypted = bytesToString(encryptedBytes);
        return encrypted;
    
    }
    
    public String Decrypt (String result) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
    {           
    
        cipher1=Cipher.getInstance("RSA");
        cipher1.init(Cipher.DECRYPT_MODE, privateKey);
        decryptedBytes = cipher1.doFinal(stringToBytes(result));
        decrypted = new String(decryptedBytes);
        return decrypted;
    
    }
    
    public  String bytesToString(byte[] b) {
        byte[] b2 = new byte[b.length + 1];
        b2[0] = 1;
        System.arraycopy(b, 0, b2, 1, b.length);
        return new BigInteger(b2).toString(36);
    }
    
    public  byte[] stringToBytes(String s) {
        byte[] b2 = new BigInteger(s, 36).toByteArray();
        return Arrays.copyOfRange(b2, 1, b2.length);
    }
    }
    
    0 讨论(0)
  • 2020-12-12 11:58

    Here is an example for Android of:

    • generating a private/public RSA key pair
    • encrypting a string
    • decrypting the encrypted string

    These methods deal with all the base 64 encoding/decoding.

        public void TestEncryptData(String dataToEncrypt) {
            // generate a new public/private key pair to test with (note. you should only do this once and keep them!)
            KeyPair kp = getKeyPair();
    
            PublicKey publicKey = kp.getPublic();
            byte[] publicKeyBytes = publicKey.getEncoded();
            String publicKeyBytesBase64 = new String(Base64.encode(publicKeyBytes, Base64.DEFAULT));
    
            PrivateKey privateKey = kp.getPrivate();
            byte[] privateKeyBytes = privateKey.getEncoded();
            String privateKeyBytesBase64 = new String(Base64.encode(privateKeyBytes, Base64.DEFAULT));
    
            // test encryption
            String encrypted = encryptRSAToString(dataToEncrypt, publicKeyBytesBase64);
    
            // test decryption
            String decrypted = decryptRSAToString(encrypted, privateKeyBytesBase64);
        }
    
        public static KeyPair getKeyPair() {
            KeyPair kp = null;
            try {
                KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                kpg.initialize(2048);
                kp = kpg.generateKeyPair();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return kp;
        }
    
        public static String encryptRSAToString(String clearText, String publicKey) {
            String encryptedBase64 = "";
            try {
                KeyFactory keyFac = KeyFactory.getInstance("RSA");
                KeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey.trim().getBytes(), Base64.DEFAULT));
                Key key = keyFac.generatePublic(keySpec);
    
                // get an RSA cipher object and print the provider
                final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
                // encrypt the plain text using the public key
                cipher.init(Cipher.ENCRYPT_MODE, key);
    
                byte[] encryptedBytes = cipher.doFinal(clearText.getBytes("UTF-8"));
                encryptedBase64 = new String(Base64.encode(encryptedBytes, Base64.DEFAULT));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return encryptedBase64.replaceAll("(\\r|\\n)", "");
        }
    
        public static String decryptRSAToString(String encryptedBase64, String privateKey) {
    
            String decryptedString = "";
            try {
                KeyFactory keyFac = KeyFactory.getInstance("RSA");
                KeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey.trim().getBytes(), Base64.DEFAULT));
                Key key = keyFac.generatePrivate(keySpec);
    
                // get an RSA cipher object and print the provider
                final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
                // encrypt the plain text using the public key
                cipher.init(Cipher.DECRYPT_MODE, key);
    
                byte[] encryptedBytes = Base64.decode(encryptedBase64, Base64.DEFAULT);
                byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
                decryptedString = new String(decryptedBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return decryptedString;
        }
    
    0 讨论(0)
  • 2020-12-12 12:01

    In RSA you should use the public key for encryption and the private key for decryption.

    Your sample code uses for encryption and decryption the public key - this can not work.

    Hence in the decryption part you should initialize the cipher this way:

    cipher1.init(Cipher.DECRYPT_MODE, privateKey);
    

    Furthermor your code has a second significant bug:

    You are converting a byte array with binary content to a String.

    Never ever convert binary data to a String!

    Strings are for string characters, not binary data. If you want to pack binary data into a String encode it to printable characters for example using Hex or Base64.

    The following example uses the hexadecimal encoder fro org.apache.common.codec package - a third party library with has to be installed.

    public byte[] RSAEncrypt(final String plain) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(2048);
        kp = kpg.genKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();
    
        cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        encryptedBytes = cipher.doFinal(plain.getBytes());
        System.out.println("EEncrypted?????" + new String(org.apache.commons.codec.binary.Hex.encodeHex(encryptedBytes)));
        return encryptedBytes;
    }
    
    public String RSADecrypt(final byte[] encryptedBytes) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    
        cipher1 = Cipher.getInstance("RSA");
        cipher1.init(Cipher.DECRYPT_MODE, privateKey);
        decryptedBytes = cipher1.doFinal(encryptedBytes);
        decrypted = new String(decryptedBytes);
        System.out.println("DDecrypted?????" + decrypted);
        return decrypted;
    }
    
    0 讨论(0)
提交回复
热议问题