web-dev-qa-db-fra.com

Décryptage RSA Encryption sous Android

J'implémente une démo pour RSA Encryption and Decryption dans Android. Je peux très bien effectuer le chiffrement, mais j'obtiens une exception: >>Java.security.InvalidKeyException: unknown key type passed to RSA.

    KeyPairGenerator kpg;
    KeyPair kp;
    PublicKey publicKey;
    PrivateKey privateKey;
    byte [] encryptedBytes,decryptedBytes;
    Cipher cipher,cipher1;
    String encrypted,decrypted;

    public String RSAEncrypt (final 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 = new String(encryptedBytes);
        System.out.println("EEncrypted?????"+encrypted);
        return encrypted;

    }

    public String RSADecrypt (final String result) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
    {

        cipher1=Cipher.getInstance("RSA");
        cipher1.init(Cipher.DECRYPT_MODE, privateKey);
        decryptedBytes = cipher1.doFinal(result.getBytes());
        decrypted = new String(decryptedBytes);
        System.out.println("DDecrypted?????"+decrypted);
        return decrypted;

    }

Et j'appelle la fonction à partir d'ici:

encrypt.setOnClickListener(new OnClickListener()
        { 
            public void onClick(View arg0) 
            {
                    try
                    {
                        RSAEncrypt rsaencrypt=new RSAEncrypt();
                        rsaencrypt.RSAEncrypt(name);

                        result=rsaencrypt.RSAEncrypt(name);
                        Toast.makeText(getBaseContext(), result.toString(),Toast.LENGTH_SHORT).show();

                        System.out.println("Result:"+result);
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                        Toast.makeText(getBaseContext(), e.toString(),Toast.LENGTH_LONG).show();
                    }
            }
        });

        decrypt.setOnClickListener(new OnClickListener()
        { 
            public void onClick(View arg0) 
            {
                {
                    try
                    {
                        RSAEncrypt rsadecrypt=new RSAEncrypt();

                        rsadecrypt.RSADecrypt(result);

                        ans=rsadecrypt.RSADecrypt(result);
                        System.out.println("Result is"+ans);
                        Toast.makeText(getBaseContext(), ans.toString(),Toast.LENGTH_LONG).show();
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                        Toast.makeText(getBaseContext(), e.toString(),Toast.LENGTH_LONG).show();
                        System.out.println("Exception is>>"+e);
                    }
            }
        });
36
Riddhi Barbhaya

Dans RSA, vous devez utiliser la clé publique pour le chiffrement et la clé privée pour le déchiffrement. 

Votre exemple de code utilise pour le cryptage et le décryptage la clé publique - cela ne peut pas fonctionner.

Par conséquent, dans la partie déchiffrement, vous devriez initialiser le chiffrement de cette façon:

cipher1.init(Cipher.DECRYPT_MODE, privateKey);

De plus, votre code a un deuxième bogue important:

Vous convertissez un tableau d'octets avec un contenu binaire en chaîne.

Ne jamais convertir des données binaires en chaîne!

Les chaînes sont pour les caractères de chaîne, pas les données binaires. Si vous souhaitez regrouper des données binaires dans une chaîne, codez-la en caractères imprimables, par exemple en utilisant Hex ou Base64.

L'exemple suivant utilise l'encodeur hexadécimal fro org.Apache.common.codec package - une bibliothèque tierce doit être installée.

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;
}
37
Robert

Ma classe:

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);
}
}
10
Elton da Costa

Voici un exemple pour Android de:

  • générer une paire de clés RSA privée/publique
  • chiffrer une chaîne
  • déchiffrer la chaîne chiffrée

Ces méthodes traitent de tous les codages/décodages en base 64. 

    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;
    }
4
seb

Je pense que le problème est que vous devez utiliser la même paire de clés pour chiffrer et déchiffrer le chiffre. En référence à JavaDoc:

 genKeyPair() This will generate a new key pair every time it is called.
1
jaredzhang

lorsque vous utilisez la méthode RSAEcvypt, ses clés de remplissage PublicKey et clé privée . Et lorsque vous décryptez votre octet généré [], votre clé publique et privateKey étant NULL ..__, vous obtenez cette erreur.

Vous devriez utiliser vos clés statiques;

enter code here

KeyPairGenerator kpg;
KeyPair kp;
static PublicKey publicKey;
static PrivateKey privateKey;
byte [] encryptedBytes,decryptedBytes;
Cipher cipher,cipher1;
String encrypted,decrypted;
0
Yiğit