Escribir la clave pública / privada en SharedPreferences y usarla
Estoy intentando cifrar y descifrar un texto con las llaves públicas / privadas. Primero de todos, creo mis llaves y las almaceno en sharedferencias con este código:
SharedPreferences SP; SharedPreferences.Editor SPE; KeyPairGenerator keyGen; KeyPair keypair; PublicKey publicKey; PrivateKey privateKey; keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024); keypair = keyGen.genKeyPair(); privateKey = keypair.getPrivate(); publicKey = keypair.getPublic(); SPE = SP.edit(); SPE.putString("PublicKey", publicKey.toString()); SPE.putString("PrivateKey", privateKey.toString()); SPE.commit();
En mi archivo SharedPreferences, las claves se escriben así:
- Android SharedPreferences, cómo guardar una variable int simple
- Cómo almacenar un valor booleano con SharedPreferences en Android?
- ListView y SharedPreferences de opción múltiple
- registerOnSharedPreferenceChangeListener no funciona para los cambios realizados en diferentes procesos
- ¿Cómo leer las SharedPreferences de otra aplicación (el mismo ID de usuario)?
PublicKey: Clave pública RSA
módulo: d07b8f32968cf65301fd710f9d6d036feac01d7b98c92ff979cd324d252cb257ff48d6630b33f0f68bd0ee81c3a83502a0abf0b263dc96c2b86940f7ec19ab1865626383e55cf5a37e25ef4eb6ca88a39f31becb6065434bc2236177aa5b35266fe0379164faea6ef7a92812e7aa3ef5fc488c70ab085f5564f09c0f6e927b49
Exponente público: 10001
PrivateKey: RSA Clave CRT privada
módulo: d07b8f32968cf65301fd710f9d6d036feac01d7b98c92ff979cd324d252cb257ff48d6630b33f0f68bd0ee81c3a83502a0abf0b263dc96c2b86940f7ec19ab1865626383e55cf5a37e25ef4eb6ca88a39f31becb6065434bc2236177aa5b35266fe0379164faea6ef7a92812e7aa3ef5fc488c70ab085f5564f09c0f6e927b49
Exponente público: 10001
exponente privado: 67ebef696c1a3fff0892e8f4bba8477a562e05844298a6cd58a5ac59401a939bc1a8f114d5d4c25c633d766640bd6c0f2f4005ef265022e6553e4220531448702e4bbf4322b9d5cf444d16eea151e5d565412b49208a73d9236607475d201affa21d374e3186f14b651b08565be4725f89fc6797a79c8433c4dd089589284a01PrimeP: ee4ad1a56f4ee3b12c198d09b08a92c349f94cc79a6143ca7140fa64c919f2d9c24c29d3b413fdc4039000b6b5feac5a764ce436db4a4a382d8ceecbc768e0d1
PrimeQ: dff9a761807440b4a5a4fb04ebaa22849f6543f33168bd6e83b3c549b346661124d7879e168c1009e97c01b3fdcd7088eebd9c989b64d7c4b81ea46f9e06d0f9
PrimeExponentP: 2ce01e371f8d25c819dbfdf9932ba593ed7c6b7f338d99aca8436a644c92fc6f11ee31fa5271695adea8e1d986d09d38b40aaaf7c1b86dddc28645fa4e656be1
PrimeExponentQ: 21904af9fc82ef5362e3474ea4763978005eef80d92da5fd92b4f4e2a77fec39b378acf50ed1ec715fd0da7c7b9336c2fe6be1b4a8ccc2dcd2ee9c9bb165ba19
CrtCoefficient: d8ccccb874ec4c2d464e84829547507e1ebf78e506caa77950b04329957b8713e80553874b825bf5c90b214984b4657b64965867460d87aab135f43930db48ec
Y con este código estoy tratando de leer estas claves:
private PublicKey getPublicKey() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException{ byte[] keyBytes = Base64.decodeBase64(SP.getString("PublicKey", "default value").getBytes("utf-8")); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(spec); return key;}
Pero algo sale mal. Da InvalidKeySpecException. Creo que esto no puede leer las claves de file.How puedo solucionar este problema? Gracias.
- Preferencias compartidas vs base de datos
- ¿Dónde se almacenan las preferencias compartidas?
- Preferencias compartidas - longitud máxima de un solo valor
- El MODE_MULTI_PROCESS de SharedPreferences es menos seguro que MODE_PRIVATE
- Actualizaciones de Android en Play Store
- Las Preferencias compartidas se pierden después de cerrar el dispositivo o de matar la aplicación.
- Cifrar datos en SharedPreferences
- Android SharedPreferences en Fragmento
De acuerdo. Encontré una solución y cambiar algo. Se trata de una nueva clase para el almacenamiento de claves públicas / privadas y su obtención de nuevo desde la cadena almacenada. Esta clase funciona para mí!
import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.util.encoders.Base64; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; public class KeyGenerator extends Activity{ SharedPreferences SP; SharedPreferences.Editor SPE; PublicKey pubKey; PrivateKey privKey; Context context; public KeyGenerator(Context context){ this.context = context; SP = context.getSharedPreferences("KeyPair", MODE_PRIVATE); } public void generateKeys(){ try { KeyPairGenerator generator; generator = KeyPairGenerator.getInstance("RSA", "BC"); generator.initialize(256, new SecureRandom()); KeyPair pair = generator.generateKeyPair(); pubKey = pair.getPublic(); privKey = pair.getPrivate(); byte[] publicKeyBytes = pubKey.getEncoded(); String pubKeyStr = new String(Base64.encode(publicKeyBytes)); byte[] privKeyBytes = privKey.getEncoded(); String privKeyStr = new String(Base64.encode(privKeyBytes)); SPE = SP.edit(); SPE.putString("PublicKey", pubKeyStr); SPE.putString("PrivateKey", privKeyStr); SPE.commit(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } } public PublicKey getPublicKey(){ String pubKeyStr = SP.getString("PublicKey", ""); byte[] sigBytes = Base64.decode(pubKeyStr); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes); KeyFactory keyFact = null; try { keyFact = KeyFactory.getInstance("RSA", "BC"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } try { return keyFact.generatePublic(x509KeySpec); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return null; } public String getPublicKeyAsString(){ return SP.getString("PublicKey", ""); } public PrivateKey getPrivateKey(){ String privKeyStr = SP.getString("PrivateKey", ""); byte[] sigBytes = Base64.decode(privKeyStr); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes); KeyFactory keyFact = null; try { keyFact = KeyFactory.getInstance("RSA", "BC"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } try { return keyFact.generatePrivate(x509KeySpec); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return null; } public String getPrivateKeyAsString(){ return SP.getString("PrivateKey", ""); } }
Gracias por el código aceptado arriba (tal vez abajo). Sin embargo, en mi caso, el 'getPrivatekey ()' lanza una InvalidKeySpecException. Dice 'Desconocido KeySpc tipo: java.secrity.spec.X509EncodedKeySpec'. La solución que he usado es reemplazar X509EncodedKeySpec con PKCS8EncodedKeySpec. Entonces funciona! Referencia: https://stackoverflow.com/a/9755391/2481444
- Reinicie el dispositivo android mediante programación
- Limpieza de caché local de dispositivos virtuales de Genymotion