[botan-devel] java pkcs8 encoding -> botan

Jack Lloyd lloyd at randombit.net
Wed Jul 25 07:24:17 EDT 2012


Hi,

It turns out this is actually a bug in PKCS8::load_key that I knew
about but somehow managed to forget. The problem is without a PEM
header it is difficult to tell if the private key is encrypted or not,
and currently the implementation simply assumes a raw binary key is
not encrypted. The workarounds are either to encrypt the key on the
Java side, or else take the base64 of the unencrypted key and wrap it
with "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----"
in which case botan will know they are not encrypted.

-Jack

On Tue, Jul 24, 2012 at 07:23:06PM -0400, Timothy Prepscius wrote:
> I'm just kidding about the ascii. :-)  
> 
> I've tried to make an absolute minimum test:
> I was hoping my bug would become obvious making this test, but so far it has not.
> 
> 
> If you want something to run you can create a java file with this:
> 
> 
> 
> ------------------- SNIP GenRSA.java
> import java.io.File;
> import java.io.FileOutputStream;
> import java.security.KeyPair;
> import java.security.KeyPairGenerator;
> import java.security.PrivateKey;
> 
> 
> public class GenRSA
> {
> 	public static void main (String[] args) throws Exception
> 	{
> 		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
> 		keyPairGenerator.initialize(2048);
> 		KeyPair keyPair = keyPairGenerator.genKeyPair();
> 		PrivateKey privateKey = keyPair.getPrivate();
> 		
> 		File fileName = new File("key.binary");
> 		FileOutputStream out = new FileOutputStream(fileName);
> 		out.write(privateKey.getEncoded());
> 		out.close();
> 		
> 		System.out.println("Wrote: " + fileName.getAbsolutePath());
> 	}
> }
> ----------------- END SNIP
> 
> compile with: javac GenRSA.java
> run with: java GenRSA
> 
> convert the file to base64 via:
> prompt$ base64 key.binary
> 
> take output, paste into test snip
> 
> 
> -----------------  START test snip
> #include <botan/botan.h>
> #include <iostream>
> #include <botan/pkcs8.h>
> #include "botan/rsa.h"
> #include "botan/pubkey.h"
> #include "botan/look_pk.h"
> #include "botan/rng.h"
> 
> using namespace Botan;
> 
> inline std::string fromBase64 (const std::string &block)
> {
> 	Botan::Pipe pipe(new Botan::Base64_Decoder);
> 	pipe.process_msg((byte *)block.data(), block.size());
> 	return pipe.read_all_as_string();
> }
> 
> int main (int argc, char *argv[])
> {
> 	try 
> 	{
> 		std::string privateKeyFromJava = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDSycLKgoy2XKsdihwTIAyBBte9cPoVPGHnmpZDz2kw8/sNnKFyRZ+bVQ/m0csrPJsCm4UgD0esxag132bHUeO0ymyUXQBzOKZ9/rtAeKeRqXE6+rqFu9YwP4+MiJTM4lx5VEucHVgm22ISXGlwXTh+Zxhbwx8Us/nyHdHaItXIPZUgPtvYowCzNBB/NVcGob6O8giM1i85rdtuMIFlzWw1Y8PlbthowmBPnD86ivgQ9uYRGVoF+5Z9w232DzlTMw42K0CIOMA9anp/cMUg+GhzX6FXj0ChO6LXsGkyOA762kZ3rz7rmOnKlJU5JHuBEHRW4HVBDo8bFSh43Pc4diyNAgMBAAECggEBAJXnNGcuRoGeD3b3dBXJ0fqkciLgSIl3oqzBzCE3TLiqmhzJCiupBePCr4dYJWN/O0G0dg0hsLhW7NQ7Ju2S+BvnZSZxqVNHs2ehE2u7Ing9hzAJhUJ8Hcu8OAsaSrAWPutuHkNMvxcLJ4ilPbrSIM4L5U/EyMLBZ3xe5pF5+ozmrCf8hmAXvRF30ddqwFs62KQA+KDRwjbBkwKOcAifnRLXk8Czv/Otw7AQ4MDpme2MzkdxDPWkpyFkVB4sjUtbDxYRg0vhiVspqqb3axrzgISvL0/8BC4w+Zl50xbnMcuEOr1dDPM89uNBAhukXMjXKXE1opCT5xwClnEprAUmEgUCgYEA782gMluK2tD+rElGoGBwMYi+zoVow92E6XIafC9a5WYh41kuCugRD8exHcOT5YUL+Sx9iD1tBqmHdswxvrC4Qel3cwGbSD5WxFz8ArYwAm2c/NtA8Vj2J7C8N4MbxUqugZH7zjmUTDcAuEHW2xx9/M0d1nzbWRtwHcsnaUAMzEcCgYEA4QZxWFGvQf6L1DY2/8eTyghqcnqhRUgRlJdKtX2imy9mDI3cGGY5hX4qb319EZLRaZwXfHo3UmocrnmyyttLa7bx8K7El5pu9pxAbJuIcxJ9FofEdosSvuywqcuSgnqqhKPVS7SpFuB7YrGyWZnyAvVOvyOxt0Ph9CSqLwB9rosCgYEA5nRQTdTXvq428U+CRkIn0BLAfCyNoB3Uy5xSg6Hm0qqySpC7xNN9AhNAzX/VNDAGb7In+bQ+gLaPbsWR0NZ4XS+HEckrd+Qg8pkBv4Fi5hJ9WitDYC3EciRQ3XBsUdARoIew3GFNeWkqkekEGJJrKXXeBPD8w8ewmZFREL7zDaUCgYAcmR4ElHUKlRgeQzmgLjQZJBKrM+yVCoC5erTS9gGZaV+1zr2fGDbNQWiRPMiNWDRnEKBngHzRa4zzm6HeaBpguSJsbTms7sKVcuw5IVcpELt3BpAwZKJgQ2J8YdPf40kSjGPKOE6ZCrSDqYO6IXeBar20SwwF94ma5qH+UTin2wKBgQDgjz/cFXTn0DDr2FEJCrVRUR1ipPuVjKNC6/0ptlejv0c/M70zXPYdJSsmNAgC0+tbyftnGk9PMoYLmE3TBWPIFLKOoFVGY19odRNicMeN/NhNsAwi9SFtnRvJdebMjb5oAKQ9+XKewlY0oLX/RdtxmvttBBdrv5gqvtvUSsGvUQ==";
> 		std::string key = fromBase64(privateKeyFromJava);
> 		
> 		AutoSeeded_RNG rng;
> 		DataSource_Memory dataSource((const unsigned char *)key.data(), key.size());
> 		PKCS8_PrivateKey *genericPrivateKey = Botan::PKCS8::load_key(dataSource, rng);
> 
> 		RSA_PrivateKey *rsaPrivateKey = 
> 			dynamic_cast<RSA_PrivateKey *> (
> 				genericPrivateKey
> 			);
> 	}
> 	catch (Exception &e)
> 	{
> 		std::cerr << e.what();
> 		return -1;
> 	}
> 		
> 	return 0;
> }
> ------------- END test snip
> 
> On Jul 24, 2012, at 3:21 PM, Timothy Prepscius wrote:
> 
> > i'm thinking of possible format problems,
> > it occurs to me that java, i think, streams big endian.
> > 
> > i wonder if the pkcs8 format declares the endian-ness to use.
> > i wonder if java is using big endian for integers in the format…
> > 
> > will go lookup format definition, for all I know it's ascii, lol :-)
> > 
> > -tim
> > 
> 

> _______________________________________________
> botan-devel mailing list
> botan-devel at randombit.net
> http://lists.randombit.net/mailman/listinfo/botan-devel




More information about the botan-devel mailing list