Uso de ECC Curve25519 para cifrar / descifrar datos en Java

Estoy tratando de utilizar Curve25519 en mi aplicación de Android para cifrar / descifrar la clave de cifrado AES localmente. No necesito ningún intercambio de claves, acuerdo clave o firma. ¿Por qué necesito usar esa curva en particular? Porque necesito ser capaz de proporcionar la llave privada yo mismo y ser capaz de calcular su correspondencia clave pública. Tan lejos como tengo, sólo Curve25519 hace esto. Por favor, corríjame si estoy equivocado.

Todas las implementaciones de Curve25519 solo hacen generación de claves, intercambio de claves y firma / verificación.

¿Es posible hacer el cifrado de datos / descifrado después de recibir Curve25519 claves privadas / públicas o tal vez usted puede sugerir cualquier alternativa curvas que coincide con mis criterios?

Editar

¿Por qué necesito esto? Voy a explicar con más cuidado. Mi aplicación está haciendo cifrado de archivos locales, en particular las fotos. Mi objetivo es que el usuario pueda tomar una foto sin ingresar una contraseña y luego ingresar la contraseña para verla. Para esto necesito ser capaz de crear el par de claves público / privado de la contraseña y ser capaz de recrear sobre la marcha el mismo par de claves siempre que se proporciona la misma contraseña. Así que en la primera ejecución que genera ECC par de claves de contraseña y almacenar la clave pública en el dispositivo. Cuando el usuario desea tomar una nueva aplicación de fotos cifra la foto con una clave aleatoria AES de 256 bits y luego cifrar esa clave con la clave pública almacenada. Cuando el usuario quiere ver la foto, él / ella proporciona la contraseña correcta, derivar el mismo par de llaves ECC y descifrar la clave AES con mi clave privada y luego puedo descifrar la foto usando AES 256.

Tan lejos como puedo obtener Curve25519 puede darme esta capacidad o hay otras alternativas. ¡Los ejemplos de código en Java son bienvenidos!

Ellos clave para cifrar archivos en un dispositivo Android es nunca almacenar la clave. A esto se ha añadido la restricción de que el cifrado de imágenes no debe requerir una contraseña. Por último, debido a que el cifrado asimétrico es lento, se necesita AES para hacer el trabajo pesado.

Esto funciona con RSA o cualquier otro algoritmo asimétrico.

Ejecución inicial

  1. En la primera ejecución, genere un par de claves y pida al usuario que introduzca una contraseña.
  2. Almacene la llave pública en claro. Cifrar la clave privada utilizando una clave AES generada a partir de la contraseña.

Cifrado

  1. Genere una clave AES diferente para cada imagen y cifre la imagen con ella. Cifrar la clave AES con la clave pública y almacenarla junto a la imagen.

Descifrado

  1. Pida al usuario que introduzca la contraseña. Genere la primera clave AES de ella. Utilícelo para descifrar la clave privada. Descifrar la clave AES para esta imagen utilizando la clave privada. Utilice la tecla AES para descifrar el archivo y mostrarlo.

(En realidad tenemos 4 claves, necesitamos el par de claves para permitirnos cifrar sin una contraseña Necesitamos la primera clave AES para almacenar la clave privada de forma segura Necesitamos la segunda y cambiando la clave AES para cifrar el archivo.

Creo que esto debería ser seguro, a excepción de ataques como el registro de claves. El código Java debe ser muy sencillo. Espero que esto esté claro.

============================================================================== ====================

Ejemplo completo Uso de AES y RSA. Para Curve, cambie el código RSA solamente, aunque no lo soporta fuera de la caja, por lo que necesitará una biblioteca externa. Además, en interés del tiempo y la brevedad, el código es menos seguro de lo que debería ser. Por ejemplo, usé ECB y no CBC.

package il.co.falk; import javax.crypto.*; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import java.security.*; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; public class SecureFile { private PublicKey publicKey; private byte[] privateKeyArray; private byte[] salt = {1,2,3,4,5,6,7,8}; public static void main(String[] args) { String password = "PASSWORD"; SecureFile secureFile = new SecureFile(password); secureFile.test(); } public void test() { String password = "PASSWORD"; String imageFile = "348756348975634897562398479623896"; ImageAndKey imageAndKey = encryptImage(imageFile.getBytes()); byte[] decryptedImage = decryptImage(imageAndKey, password); System.out.println(new String(imageFile)); System.out.println(new String(decryptedImage)); } public SecureFile(String password) { try { generateRSAKeys(password); } catch (Exception e) { e.printStackTrace(); } } public ImageAndKey encryptImage(byte[] imageBytes) { try { byte[] secretKeyBytes = generateAESKey(); byte[] encryptedFile = aesEncrypt(imageBytes, secretKeyBytes); byte[] encryptedKey = rsaEncrypt(secretKeyBytes); return new ImageAndKey(encryptedFile, encryptedKey); } catch (Exception e) { e.printStackTrace(); return null; } } public byte[] decryptImage(ImageAndKey imageAndKey, String password) { try { byte[] secretKeyBytes = generateAESKey(password); byte[] decryptedPrivateKey = aesDecrypt(privateKeyArray, secretKeyBytes); byte[] decryptedKey = rsaDecrypt(imageAndKey.aesKey, decryptedPrivateKey); SecretKey secretKey = new SecretKeySpec(decryptedKey, "AES"); secretKeyBytes = secretKey.getEncoded(); byte[] decryptedBytes = aesDecrypt(imageAndKey.imageBytes, secretKeyBytes); return decryptedBytes; } catch (Exception e) { e.printStackTrace(); } return null; } // RSA private void generateRSAKeys(String password) throws Exception { final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(512); // TODO: make this 2048 at least final KeyPair keyPair = keyGen.generateKeyPair(); publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); byte[] secretKeyBytes = generateAESKey(password); byte[] privateKeyBytes = privateKey.getEncoded(); privateKeyArray = aesEncrypt(privateKeyBytes, secretKeyBytes); } public byte[] rsaEncrypt(byte[] plainText) throws Exception { final Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] cipherText = cipher.doFinal(plainText); return cipherText; } public byte[] rsaDecrypt(byte[] cipherText, byte[] decryptedPrivateKeyArray) throws Exception { PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decryptedPrivateKeyArray)); final Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] plainText = cipher.doFinal(cipherText); return plainText; } // AES private byte[] aesEncrypt(byte[] plainText, byte[] secretKeyBytes) throws Exception { Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKeyBytes)); byte[] cipherText = cipher.doFinal(plainText); return cipherText; } public byte[] aesDecrypt(byte[] cipherText, byte[] secretKeyBytes) throws Exception { Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKeyBytes)); byte[] plainText = cipher.doFinal(cipherText); return plainText; } private byte[] generateAESKey() throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); SecretKey secretKey = keyGen.generateKey(); return secretKey.getEncoded(); } private byte[] generateAESKey(String password) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); return secret.getEncoded(); } private SecretKey getSecretKey(byte[] secretKeyBytes) throws Exception { SecretKey secretKey = new SecretKeySpec(secretKeyBytes, "AES"); return secretKey; } // Classes class ImageAndKey { public byte[] imageBytes; public byte[] aesKey; public ImageAndKey(byte[] imageBytes, byte[] aesKey) { this.imageBytes = imageBytes; this.aesKey = aesKey; } } 

}

  • ¿Qué lenguajes de programación puedo usar en Android Dalvik?
  • ¿Qué significa '->' (flecha) en el gráfico de dependencia del gradle?
  • Precargar algunas imágenes para listview con UniversalImageLoader
  • Problemas al crear la aplicación GCM Demo Server
  • ¿Cómo puedo obtener un Android TableLayout para llenar la pantalla?
  • ProcessInputStream.finalize () se ha agotado después de 10 segundos
  • Bloquear / desbloquear una aplicación de mi aplicación: Android
  • Depuración después de reactivar una actividad
  • ¿Por qué Butterknife no puede encontrar un ViewHolder dentro de una clase anónima?
  • ¿Cómo puedo determinar las coordenadas de longitud y latitud para crear un radio de 1 milla alrededor de la ubicación de un usuario?
  • Cómo implementar gesto de desplazamiento en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.