[APORTE] Funciones principales OpenPGP.js

Iniciado por arget, 31 Agosto 2015, 22:00 PM

0 Miembros y 1 Visitante están viendo este tema.

arget

Esto empezó como una duda, pero mientras la explicaba pude resolver el problema, aunque, la verdad, me costó bastante, así que he decidido mostrar una explicación de las funciones de OpenPGP.js. Costó bastante resolver algunos problemas porque hay poca documentación, y la que hay es poco explicativa, y como imagino que habrá gente en mi misma situación, pues aquí pongo las soluciones a los problemas que me planteé; también, para presentar un manual medianamente completo, he estudiado algunas funciones que no necesitaba, o también añado mi implementación de algunas funciones que sí están bien documentadas [el caso de generateKeyPair(), de encryptMessage() y decryptMessage()].
Sinceramente no sé dónde colocar esto, he leído las normas del subforo y dice que solo dudas, no sé si valdrán aportes.

OpenPGP.js es una librería en javascript que implementa, si no todas, prácticamente todas las funciones del protocolo OpenPGP.
Su página de GitHub: http://www.github.com/openpgpjs/openpgpjs
El corazón de la librería está en /dist/ y se llama openpgp.js (no se va a llamar sardinasEnlatadas.js) .
Así que a partir de ahora lo incluimos siempre en la cabeza:
<script src="openpgp.js" type="text/javascript"></script>
Todas las funciones ya vienen en ese archivo, de manera que no hace falta almacenar el resto del proyecto.

Bueno, empecemos con el código:



Generar un keypair (pareja de claves, pública y privada):
Código (javascript) [Seleccionar]

//Especificamos la contrasena con la que se cifrara la clave privada
var pass = "holasoyunacontrasena";
//Definimos el email del propietario de las claves
var email = '<' + document.getElementById("mail").value + '>';
//El nombre de usuario
var user = document.getElementById("user").value;

//Se juntan nombre de usuario e email para formar el KeyID
var id = user + ' ' + email;

//Generamos las claves
var clave = openpgp  //   Tamano    KeyID        Contrasena
.generateKeyPair({numBits: 2048, userId: id, passphrase: pass})
.then(function(keyPair)
{   //Mostramos los resultados
   document.write('<pre>' + keyPair.privateKeyArmored + '</pre>');
   document.write('<pre>' + keyPair.publicKeyArmored + '</pre>');
});


Cifrar:
Código (javascript) [Seleccionar]

//Definimos la clave publica con la que cifrar
var key = '-----BEGIN PGP PUBLIC KEY BLOCK----- . . .';
//Leemos dicha clave
var publicKey = openpgp.key.readArmored(key);

//Ciframos
openpgp.encryptMessage
(
   publicKey.keys, //Clave publica
   "Message"       //Mensaje a cifrar
)
.then(function(pgpMessage){
   //Mostramos el resultado
   document.write('<pre>' + pgpMessage + '</pre>');
})


Descifrar:
Código (javascript) [Seleccionar]

//Definimos la clave privada para descifrar
var key = '-----BEGIN PGP PRIVATE KEY BLOCK----- . . .';
//La leemos
var privateKey = openpgp.key.readArmored(key).keys[0];
//La desciframos con la contrasena
privateKey.decrypt("holasoyunacontrasena");

//Definimos el mensaje cifrado
var pgpMessage = '-----BEGIN PGP MESSAGE----- . . .';
//Leemos el mensaje
pgpMessage = openpgp.message.readArmored(pgpMessage);

//Desciframos
openpgp.decryptMessage
(
   privateKey,
   pgpMessage
)
.then(function(plaintext){
    //Mostramos el resultado
    document.write('<pre>' + plaintext + '</pre>');
})


Firmar:
Código (javascript) [Seleccionar]

//Definimos clave privada
var PVK = '-----BEGIN PGP PRIVATE KEY BLOCK----- . . .';
//La leemos
var privKeys = openpgp.key.readArmored(PVK);
var privKey = privKeys.keys[0];
//La desciframos
privKey.decrypt("holasoyunacontrasena");
//Firmamos
openpgp.signClearMessage
(
   privKeys.keys, //Clave privada
   "Message"      //Mensaje
)
.then(function(signed)
{
   //Mostramos el mensaje firmado
   document.write('<pre>' + signed + '</pre>');
});


Verificar:
Código (javascript) [Seleccionar]

//Indicamos la clave publica
var PBK = '-----BEGIN PGP PUBLIC KEY BLOCK----- . . .';
//La leemos
var publicKeys = openpgp.key.readArmored(PBK);
//Definimos el mensaje firmado, con sus dos partes, el mensaje y la firma
var tmp = '-----BEGIN PGP SIGNED MESSAGE----- . . .';
//Leemos el mensaje firmado
var message = openpgp.cleartext.readArmored(tmp);
//Verificamos
openpgp.verifyClearSignedMessage
(
   publicKeys.keys, //Clave pública
   message          //Mensaje firmado
)
.then(function(verified)
{
   if(verified.signatures[0].valid == true)
   {   //Si la firma es valida
       document.write(verified.text); //Muestra el contenido del mensaje
       document.write('<pre>FIRMA VALIDA!</pre>');
   }
   else
   {   //Si NO es valida
       document.write('<pre>¡FIRMA NO VALIDA!</pre>');
   }
});


Firmar y cifrar (este particularmente me costó lograr que funcione):
Código (javascript) [Seleccionar]

//Se define la clave publica (con la que se cifra)
var PBK = '-----BEGIN PGP PUBLIC KEY BLOCK----- . . .';
//Se define la clave privada (con la que se firma)
var PVK = '-----BEGIN PGP PRIVATE KEY BLOCK----- . . .';

//Leemos ambas claves
var publicKey = openpgp.key.readArmored(PBK);
var privateKey = openpgp.key.readArmored(PVK).keys[0];

//Desciframos con nuestra contrasena la clave privada
privateKey.decrypt("holasoyunacontrasena");

//Firmamos y ciframos
openpgp.signAndEncryptMessage
(
   publicKey.keys, //Clave publica
   privateKey,       //Clave privada
   "Message"        //Mensaje a procesar
)
.then(function(pgpMessage)
{   //Mostramos el resultado
   document.write('<pre>\n' + pgpMessage + '</pre>');
})


Descifrar y verificar (este también fue un lío dominarlo):
Código (javascript) [Seleccionar]

//Claves
var PBK = '-----BEGIN PGP PUBLIC KEY BLOCK----- . . .';
var PVK = '-----BEGIN PGP PRIVATE KEY BLOCK----- . . .';
//Leemos
var publicKeys = openpgp.key.readArmored(PBK);
var privateKey = openpgp.key.readArmored(PVK).keys[0];
//Desciframos
privateKey.decrypt("holasoyunacontrasena");

//Mensaje
var pgpMessage = '-----BEGIN PGP MESSAGE----- . . .';
//Leemos mensaje
message = openpgp.message.readArmored(pgpMessage);
//Desciframos y verificamos
openpgp.decryptAndVerifyMessage
(
   privateKey, //Clave privada
   publicKeys.keys, //Clave pública
   message //Mensaje firmado y cifrado
)
.then(function(verified)
{
   if(verified.signatures[0].valid == true)
   {//Si es valida la firma
       document.write(verified.text); //Esto muestra el contenido del mensaje
       document.write("VALIDA!"); //Indicamos su validez
   }
   else
   {//Si NO es valida
       document.write("NO VALIDA!"); //Indicamos su invalidez
   }
});


Si alguno no funciona, avisadme, por favor...
La gestión manual de bloques de memoria en C es como hacer malabarismos con pastillas de jabón en la ducha de la prisión: todo diversión hasta que cometes un fallo.