Miraste RSAKeyPairGenerator
( doc. ) ( ¿Fuente ) de BouncyCastle ? Genera un par de claves RSA y lo codifica. Apuesto a que puedes crear un objeto de par de llaves, llenarlo con tus valores y llamar a la función de codificación para obtener un archivo que acepte gpg.
EDIT :
He utilizado openssl para generar un par de llaves RSA y exportar los valores de sus componentes:
openssl genrsa -out rsa1024.pem 1024
openssl rsa -noout -text -in rsa1024.pem
He eliminado los separadores de bytes de dos puntos y las nuevas líneas de los valores de big int y he rellenado el exponente para que sea un número par de nibbles en hexadecimal.
Si aplica el siguiente parche a este archivo:
--- bcpg-jdk15on-152/org/bouncycastle/openpgp/examples/RSAKeyPairGenerator.java 2015-03-01 12:03:48.000000000 +0200
+++ src/foo/RSAKeyPairGenerator.java 2015-05-19 23:07:00.754583435 +0300
@@ -1,11 +1,13 @@
-package org.bouncycastle.openpgp.examples;
+package foo;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
-import java.security.KeyPairGenerator;
+//import java.security.KeyPairGenerator;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.SignatureException;
@@ -13,6 +15,10 @@
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
+import org.bouncycastle.crypto.params.RSAKeyParameters;
+import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey;
+import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
@@ -76,11 +82,34 @@
{
Security.addProvider(new BouncyCastleProvider());
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
+ //KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
- kpg.initialize(1024);
+ //kpg.initialize(1024);
- KeyPair kp = kpg.generateKeyPair();
+ //KeyPair kp = kpg.generateKeyPair();
+
+ BigInteger modulus = new BigInteger("00f4035469c2adf91d69052f94a8d466cae6ea485ecfd0dc6b1d408e8ef36ef2a60d907234c4e9e8e1261e42008a41140134fc62840338433ab5948b96ceb91b65b0aacf8b54deca21a90386ebe17df16ebd1bef137ba8a43e9e2671ecd0bc5cd052321d50e61eac532cf718309f76760b9e68690897d76a5f9955541f3bd87a89", 16);
+ BigInteger publicExponent = new BigInteger("010001", 16);
+ BigInteger privateExponent = new BigInteger("00abfc6cd2de54a0f109c48df4c9ca6b6937b889a9c9effc6bc3026d78743c0eeadb44a43a6d5030c40089f31b4e56f032a995fa19f1eb05f7ab6437bee395b4a867af07b71b8515728b44fed0f5c85367e182a00a8df3df3098b82e74f224b294c90e261869c81fb9b89824bec026b7189bad0c11d4366636e2d357ca06e591c1", 16);
+ BigInteger p = new BigInteger("00fdd4b067e9361abe40231470f8249e68d64aeade1828dcd8b60cb33942df55bb6806fa81784b5fc24f73d8313baac2c0150307e56df621c77cc650b2b6996193", 16);
+ BigInteger q = new BigInteger("00f619297aa83e72f5a0c9b0df87c1bb0927c17d70cf99c6a9f6c58ddbb848d40abdd0c853baf7de55ac8dfe84ba38d12e86703e4b82273066c252369a5f3534f3", 16);
+ BigInteger dP = new BigInteger("4dbd9e69b4db85454f8f6eeb4a94ac8f9f5242acd2e970fa4e87853cbc667a737360efc847778e548cd1061dce1076a52dca47d8d4dcd56baba37183cab91f51", 16);
+ BigInteger dQ = new BigInteger("64232af0a103002e1865d955ab5cd6294c86fbeeea5a6d2efd9db7325f932accd01de355c6af5345d337d807d3ea889b80d2ad56763852068e2d7bd066cb34a7", 16);
+ BigInteger qInv = new BigInteger("00c9cbb6242b3e748d557e12cbacaa4b3e5a7fd0573fcc31b77268a492e270055628a02a46ff4cefbdff28aaea289faca9826d8e22cf5b0f4de2e15bdd4b3d3d14", 16);
+
+ RSAKeyParameters pubkey_params = new RSAKeyParameters(false, modulus, publicExponent);
+ RSAPrivateCrtKeyParameters privkey_params = new RSAPrivateCrtKeyParameters(
+ modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv);
+
+ Constructor<BCRSAPublicKey> pubkeyctor = BCRSAPublicKey.class.getDeclaredConstructor(RSAKeyParameters.class);
+ pubkeyctor.setAccessible(true);
+ BCRSAPublicKey pubkey = pubkeyctor.newInstance(pubkey_params);
+
+ Constructor<BCRSAPrivateCrtKey> privkeyctor = BCRSAPrivateCrtKey.class.getDeclaredConstructor(RSAPrivateCrtKeyParameters.class);
+ privkeyctor.setAccessible(true);
+ BCRSAPrivateCrtKey privkey = privkeyctor.newInstance(privkey_params);
+
+ KeyPair kp = new KeyPair(pubkey, privkey);
if (args.length < 2)
{
Obtendrá un programa que cuando se ejecuta con argumentos "-a contraseña foo" produce archivos pub.asc y secret.asc que son un par de llaves pgp.
EDIT 2 :
$ pgpdump secret.asc
Old: Secret Key Packet(tag 5)(510 bytes)
Ver 4 - new
Public key creation time - Tue May 19 22:56:20 IDT 2015
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(1024 bits) - ...
RSA e(17 bits) - ...
Sym alg - CAST5(sym 3)
Iterated and salted string-to-key(s2k 3):
Hash alg - SHA1(hash 2)
Salt - 3b b9 cf f9 02 cf 90 9e
Count - 65536(coded count 96)
IV - d8 ac aa 96 61 7a 03 34
Encrypted RSA d
Encrypted RSA p
Encrypted RSA q
Encrypted RSA u
Encrypted SHA1 hash
Old: User ID Packet(tag 13)(2 bytes)
User ID - id
Old: Signature Packet(tag 2)(156 bytes)
Ver 4 - new
Sig type - Generic certification of a User ID and Public Key packet(0x10).
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - SHA1(hash 2)
Hashed Sub: signature creation time(sub 2)(4 bytes)
Time - Tue May 19 22:56:20 IDT 2015
Sub: issuer key ID(sub 16)(8 bytes)
Key ID - 0xB01AC717560C7F68
Hash left 2 bytes - ee a9
RSA m^d mod n(1024 bits) - ...
-> PKCS-1