Cifrar y descifrar datos usando algoritmos de clave asimétrica con Java

Escrito por el .
java planeta-codigo
Enlace permanente Comentarios

El lenguaje de programación Java ofrece clases e implementa varios algoritmos relacionados con la criptografía y seguridad. Con unas pocas líneas de código es posible listar los algoritmos soportados, generar claves, cifrar datos y descifrar datos. Soporta tanto criptografía de clave simétrica donde se usa la misma clave tanto para cifrar como para descifrar y como en este artículo se muestra criptografía asimétrica en la que se utiliza dos claves una la clave pública para cifrar datos y la clave privada para descifrar los datos.

Java

Los algoritmos de clave simétrica que utilizan la misma clave para cifrar como para descifrar adolecen del problema conocido como man-in-the-middle, el problema consiste en que no es posible compartir la clave privada entre el emisor y receptor del mensaje con garantía de que un intermediario no la haya alterado.

Aún con este problema los algoritmos de clave simétrica siguen siendo utilizados ya que tienen otras ventajas. Los algoritmos de clave asimétrica no tienen el problema de man-in-the-middle aunque tienen otros defectos.

En el lenguaje de programación Java es posible generar un par de claves asimétricas, cifrar datos con la clave pública y descifrar los datos con la clave privada.

Los algoritmos de clave asimétrica

Los algoritmos de clave asimétrica utilizan una clave para cifrar los datos y otra clave para descifrar los datos. Ambas claves están relacionadas matemáticamente de tal forma que los datos cifrados con una clave solo son descifrables por su clave asociada.

A una de las claves se le denomina clave pública porque esta puede ser compartida, es la que se utiliza para cifrar los datos que solo pueden ser descifrados por la clave privada. La clave privada se denomina así porque ha de mantenerse en secreto.

Varios algoritmos conocidos de clave asimétrica son los siguientes:

Asymetric encryption keys Pulbic key encryption

Asymmetric encryption keys and public key encryption

Longitud de las claves

Los algoritmos de clave asimétrica necesitan claves más largas, de mayor número de bits, que las de los algoritmos de clave simétrica para ofrecer el mismo nivel de seguridad.

Algunos algoritmos de clave asimétrica permiten claves de 8192 bits de longitud aunque ya longitudes de 2048 bits se consideran seguros. Por el contrario los algoritmos de clave simétrica ofrecen con longitudes de 256 bits una seguridad equivalente.

Utilizar algoritmos de clave asimétrica con Java

El lenguaje de programación Java soporta varios algoritmos de clave asimétrica, la generación de claves privada y pública, cifrado y descifrado de datos con las claves. Proporciona varias clases en el JDK disponibles para cualquier aplicación sin necesidad de librerías de terceros.

Para casos avanzados o tareas específicas en el ecosistema Java hay librerías en el ámbito de la seguridad y criptografía que se pueden añadir como una dependencia en un proyecto, una de ellas es Bouncy Castle.

Esta es la salida del programa en la que se muestra el texto de datos, el texto cifrado y el texto original descifrado y la clave privada y pública representada en formato PEM.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
Asymetric encryption
Supported key generators: DIFFIEHELLMAN,DSA,EC,ED25519,ED448,EDDSA,RSA,RSASSA-PSS,X25519,X448,XDH
Private key: 
-----BEGIN RSA PRIVATE KEY-----
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
tmhlurTe5g/lsgLGrHqj3gW8S4rTQQ==
-----END RSA PRIVATE KEY-----

Public key: 
-----BEGIN RSA PUBLIC KEY-----
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEApYILhoS9Y9juHpSgaHhx
ShSOgQoQfyYEXz9lkSOkVT0cqkX4C9LcTM9VDfYJD7JYxWIYmWKgXiCT+sjLJR71
AWa+3zN5OX+Hrxsjhr811QyRmMbOlcURygvfzGck5rh0v65RmPIFzr1fa6NCupP7
hbufWVDpE0VAi7b9++rW1yPR14WDyij/5yxmh3TZMqhzBE0y1paTZbbBE6dB1i3k
jMrY6n/cRQb81KO++Yanv6vLYBCG+n38s62BVH5o1MZuKoQCOGs6zhmIdUj5mupy
1rv2LmfeI+FfYPfuQlejKuywE6lOHGA1OLH1qZAwNM2150E9Cg3MIP0B0Ndn9oMr
b2jR9hvEheVsBUUKi3KUbQ6Z5MXxEz6XMZY8tbJWU3pdIze3/4vwg7rb/0ifPviJ
7NrVj3v42DLtFka70ZXxNDgcQwbSKtvVMqDiP5fl0iBZmvDYh+fM7B8QFBIV6i0f
JnQfvlHjc6S33LSGKoGy8+LCGZBYJzFwoaWRDLaIoyQRf9hZBl3JcHK3gOshMm3r
LoIpL2mp4jAhL1H0qu2hdbdlXTHaozQXRtzyBs4JbcorVPK3EKNUwd+IGqDA5l+s
o7+twCj54aUF7mX4PyYU7jrqNliz4gI90vuughh2S3LY6rC0IymPJErOv5TWh6bH
no8MdZF5ekOIEOTpipk3LUu68SCSdGCrAjJX+yCqghkIxvbuDZkUNrEPYUuOrVgk
AS6Ge+ELvD6fzE3JIuxC8SmwoMylW3Fv8Vv+Dk7SuOwecrNDL8rf5xxiu0b1nAlz
AJ+BdwhzwTkN6UvOczMvKZD7Eo/ZDjr3vOLW4GC3b6i8y/WU7mQLWYrF2CWl8BxQ
geDXyHEXuMMBF47CXIsSgZTTYZsbs+w7W7oNHuaBBWmV/MX1p2AhjWbi/v5EuwDg
6XWbsKCy1vxPRRq+Rs9a4kGDaOZ+2MUSZLTX7EAl1n/N94sFxHqE50r3/HSgvjEB
4fbxsuPnNLO2h4z4nQP/ya3ry93oh7IPIhZH8usyJVYl+bspxosEGaOKFdIF8HJy
QV77M2OqZXF5iebvFBQImbzkrBvGupHaDqdQqDPc7fHHsorvSP0B7Zy/2rgaSVZp
KsbU9N6sqISx+Nh4zetpxAlBkLujmL48je/cEilmupt76L5X7uOAy2nWtt9hHDcK
hKgo6XYUQy4nUttyREXCpeQ2h+mGvbn5psMUi8BjPZzYu/JyYPMHqMpY9+MjAmE8
zBgvhq0F28hhUhWNvgbsfWJq5DP8DKw/frA+VXEO+eiKiIzLsvOnMZwoaTvx1Hyu
1BuZeh5ZHx0MlDCDaLgT+FPz0J+22cSTXgo3OJKv3EqxGEWw8BGwATn8iGyIig7r
yQIDAQAB
-----END RSA PUBLIC KEY-----

Plain text: rw@wbnaq2R@DS#u3o7hxWckqhfkzbT
Public key encrypted: 2a23a9a4333fa3938430db718f8e7162d312db0754a7cc0ac138c6940ea5cb10e6347d56f72a8dca950df89cd05d60493c4e9d7eff7fdb52fdadda23b707082c25a2eaa1ab8c7d19dbedb0549430320271b33576923e389ad56087a381aa1969b0c8f19355b70ae169d17f391853e1686dfc09b46e410b635c027ab8b3cec67bb33c52db2a2decd11c52bc7cb77aad336992207c0a9cd02b4ffda70ac398529312961c1b60153cd3c38dd6f9a10f048c73b725e13061b424dbd856e6f39eaa5550e7970568048cb02ca4f02c2f976f2bfbde43f5fd55f256bee4f71fde0171174132fa62052905850343f8cf90a01362b7e7a564b8f0616d9bb1ed42901959a060206d0154f3563836d2ba052bb47b399c3f33d7cd9f341f18e7d76c113af543be3f2332dcdddfe0596708f315b77643b61826865b4c19d2495220fc8174334c6048459be46fa39c455b30b0920361828a14fa9bc0f17e2b8b8386951c528e147ed2a10f0dda2a2c6ebaf850006a97a59e4eff4e558807318514e72e14e2315275bf9c6d27c5d63c300f23750b1dba8e3bfa2b8db9981dbe2075877b3b6c300baeca37640cef0af4c23db6680e90e12e657ed2d278613b76360549dbaf6ab800a508d3a3fd7086d91182f08c9eb5683c3f380f3a0f0352a539160e4034af26849317e789b0506ff17d8abed6fcb1dbf065b75303a00b50681bcfccbf2bf075d3664f5397ab580235a3345534c3fc4fd9649572c6e8911f4abfcfa489de8c0b97d2a399dd11541b4318dcc8a821fa89701339c391c777476e2db0e9758cccf38bbea8eb6ee199166fe92f93c73c9a75806172021da60d3bb7fb8569124bfa8cde3e97421ad81692bbd53fbf68189b472c78198d396f51618c4ca7eed7dc8cfaa5c62e32f9ffdb9139b9cd8226f54584d06cdc85c211cf78f5e2870e666c6ed75ad50eb2adc706c4b37aa897367b7d77fe1c5bad994817fced3d59cd0d79303075f732a912ee990e642bc0e963912c8f6724dc4453a73e2a5e3d6c229427ec9a85b50d31513cefb46dc207383cf7af294d2fa8f7d9b83887a8ecd9628ff825b6060e20b4194b1c55d53a605ad456600dca14796fabb031497358f93d639504e8897845ff83f359752fa729d624339a2ba57dfdb4c1ce5330048c2d956a8c379fae84756be6ee4bc30ad248e08147573f9bc945caff686904df9d73be328e04705bc1e8f208fa5279435c16fed6a7b0b6ecc863550759cda0cd6fea3780078286d66d051e800635b9f5ea5b7b1f40d1d9982476fb60c7a652f857f154855a85955cfc61a5758dc0c9e43da873a4e18eda0f0bf32b33e21c4942df73857f64aa1622117ad1a8aabe8ff2ea614f00c68db364e24e5452aeb9fcc83596a4afa785fda58314f0c0d4753201e9a9358d7c359f5627bae0601fca5eabb9cca69b8a6c3f61
Private key decrypted: rw@wbnaq2R@DS#u3o7hxWckqhfkzbT
Main.out
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
plugins {
    id 'application'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation('org.bouncycastle:bcprov-jdk18on:1.72')
    implementation 'org.bouncycastle:bcpkix-jdk18on:1.72'
}

application {
    mainClass = 'io.github.picodotdev.blogbitix.javahashingencrypt.Main'
}
build.gradle

Listar algoritmos de clave asimétrica

El siguiente código permite obtener que algoritmos soporta un determinado servicio de seguridad proporcionado por Java, en este caso el servicio para generar claves asimétricas. En el caso de Java 17 se soportan los algoritmos DSA y RSA.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package io.github.picodotdev.blogbitix.javahashingencrypt;

...

public class Main {

    public static void main(String[] args) throws Exception {
        ...

        System.out.println("");
        System.out.println("Asymmetric encryption");
        asymmetricEncrypt();
    }

    private static void asymmetricEncrypt() throws Exception {
        Set<String> keypairGenerators = Security.getAlgorithms("KeyPairGenerator");
        System.out.println("Supported key generators: " + keypairGenerators.stream().sorted().collect(Collectors.joining(",")));

        ...
    }

    ...
}

Main-1.java

Generar un par de claves privada y pública

Antes de poder cifrar y descifrar datos con clave asimétrica hay que generar las claves privada y pública, son dos claves diferentes pero que están relacionadas matemáticamente y se generan al mismo tiempo.

Uno de los parámetros de configuración al generar las claves es la longitud de bits de las claves, a mayor longitud mayor seguridad con una mayor capacidad de cálculo requerido para el cifrado y descifrado. En el ejemplo se generan las claves con una longitud de 8192 bits que es un tamaño muy superior al necesario para la clave en los algoritmos de clave simétrica.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package io.github.picodotdev.blogbitix.javahashingencrypt;

...

public class Main {

    ...

    private static void asymmetricEncrypt() throws Exception {
        ...

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(8192);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        System.out.println("Private key: \n" + encodePem(privateKey));
        System.out.println("Public key: \n" + encodePem(publicKey));

        ...
    }

    ...
}

Main-2.java

Codificar la clave privada y pública en formato PEM

Las claves se suelen codificar en formato PEM y guardar en un archivo de texto. Java no ofrece una clase para realizar la codificación en un archivo PEM por lo que en este ejemplo se utilizan las clases PemObject y JcaPEMWriter de la librería Bouncy Castle.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package io.github.picodotdev.blogbitix.javahashingencrypt;

...

public class Main {

    ...

    private static void asymmetricEncrypt() throws Exception {
        ...

        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        System.out.println("Private key: \n" + encodePem(privateKey));
        System.out.println("Public key: \n" + encodePem(publicKey));

        byte[] encrypted = encrypt(publicKey, text);
        String decrypted = new String(decrypt(privateKey, encrypted));

        System.out.println("Plain text: " + text);
        System.out.println("Public key encrypted: " + HexFormat.of().formatHex(encrypted));
        System.out.println("Private key decrypted: " + decrypted);
    }

    ...

    public static String encodePem(PrivateKey privateKey) throws Exception {
        PemObject privateKeyPemObject = new PemObject("RSA PRIVATE KEY", privateKey.getEncoded());
        StringWriter stringWriter = new StringWriter();
        JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter);
        pemWriter.writeObject(privateKeyPemObject);
        pemWriter.close();
        return stringWriter.toString();
    }

    public static String encodePem(PublicKey publicKey) throws Exception {
        PemObject privateKeyPemObject = new PemObject("RSA PUBLIC KEY", publicKey.getEncoded());
        StringWriter stringWriter = new StringWriter();
        JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter);
        pemWriter.writeObject(privateKeyPemObject);
        pemWriter.close();
        return stringWriter.toString();
    }
}

Main-3.java

Cifrar datos con la clave pública

El proceso de cifrado de datos en un algoritmo de clave asimétrica se realiza con la clave pública. El proceso de cifrado con la clave pública es similar a como se hace con un algoritmo de clave simétrica.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package io.github.picodotdev.blogbitix.javahashingencrypt;

...

public class Main {

    ...

    private static void asymmetricEncrypt() throws Exception {
        ...

        String text = "rw@wbnaq2R@DS#u3o7hxWckqhfkzbT";

        byte[] encrypted = encrypt(publicKey, text);
        String decrypted = new String(decrypt(privateKey, encrypted));

        System.out.println("Plain text: " + text);
        System.out.println("Public key encrypted: " + HexFormat.of().formatHex(encrypted));
        System.out.println("Private key decrypted: " + decrypted);
    }

    ...

    private static byte[] encrypt(PublicKey publicKey, String text) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(text.getBytes());
    }

    ...
}
Main-4.java

Descifrar datos con la clave privada

Los datos cifrados con la clave pública sólo es posible con la clave privada. El proceso de descifrado también es muy similar al descifrado con una clave simétrica.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package io.github.picodotdev.blogbitix.javahashingencrypt;

...

public class Main {

    ...

    private static void asymmetricEncrypt() throws Exception {
        ...

        String text = "rw@wbnaq2R@DS#u3o7hxWckqhfkzbT";

        byte[] encrypted = encrypt(publicKey, text);
        String decrypted = new String(decrypt(privateKey, encrypted));

        System.out.println("Plain text: " + text);
        System.out.println("Public key encrypted: " + HexFormat.of().formatHex(encrypted));
        System.out.println("Private key decrypted: " + decrypted);
    }

    ...

    private static byte[] decrypt(PrivateKey key, byte[] encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(encrypted);
    }

    ...
}
Main-5.java
Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./gradlew run

Referencia:


Comparte el artículo: