2

It seems x509 cert request can only be generated by Openssl that Java has no control over that. So I decided to invoke Openssl command in Java; my system is Windows7-64bit, JDK 1.7, Openssl 1.02 binary distribution.

Generating CSR request is good via direct Openssl command, but invoking the same command in Java reports an error.

Openssl command:

openssl req -new -key bob.pem -out bob.csr -subj /C=CN

Java code:

Process p;
String command="openssl req -new -key bob.pem -out bob.csr -subj /C=CN";
Runtime r=Runtime.getRuntime();
p=r.exec(command);

Error message:

unable to load Private Key
8016:error:0906D06C:PEM routines:PEM_read_bio:no start line:.\crypto\pem\pem_lib.c:701:Expecting: ANY PRIVATE KEY

The .pem is indeed private key generated by openssl. Please give me hand. Thanks.

bob.pem is generated via this command:

openssl genrsa -out bob.pem

-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEA25I5wAAGJIBvQtLXghdCjwDuNTbIQX9ISx4ZRDL5CQl8WU7U
vxEnGxJHiJBPE1aJOXSL12LGgzgsnw7G5MIMsJoGI929H8VaiM+iU96+eA6TE6xu
5DheApLiUwq62fybHg1bnXZlHhXUSIQYhTT2dvYMVXnhKO99siLIcKG8LK3H1JUE
KGKShO+0skiA0f70J8hFSGgeB2VCClMkEgoGslYkYnlKNNP38rEWaQdlQdVZGu4q
8okkRcsHsG0vJRx5G7uateoo8uWwqMhVF1tLEcYAYJhOOInofo6MVyqdZ55i8DTb
IPv80kMqx4tmxDN4Q+yjN6PpgijWIG0fA0GlcQIDAQABAoIBAQDNlxkjweH+g5Oq
Ciln0ceshr6EbQsM6NUUINafmOq9n3gjV0C0tqbbHj6EjDq+bKSIe6wEvKQLcam2
NOvefiPLqCxfoNvYx72BpIjl5waI+3yTSz15y52a41WvU7ipK3FCrlc+FQGRLfda
/vTGpVSxBql9z2UYI0aaaR8s9wNvAHzBbfbGTE0JpmTbviyZipj0y18Dykqt5eUO
Wj1Ox0+0hkub7vbVjRIRBUDdsxvLcPZMwPQwdWOsuTH/3wxe/bqczVPVlbDBDok/
xmwd03pqh0+78I6BP/r9eyxwwwe2L94lf+zsojsIu17WlzH9fGhAxfkixTA8TM8l
L/Y1LAgBAoGBAO4gBAaY4VCcoYcGoDbzOXbRBHgN/gvmtVuakidpwA+RSiO2cqgz
bik0d5sSWLqbbxXta+aQdUwX9ngeWUm2dugZP3umkjUfCvrsic6QxiX7up0M5OYF
ukFMaUL0ukr8g7VIA2JaXheia9gEIMnDTbjebA+J/qIUujqfdOACIQ1RAoGBAOwN
qk3kZajPV/Ja3Ij7mAGa5dPwomFTKfBUwbj8cMDDNK+LsR2SpPh8aaIsoWCUwgCB
O3E3TSXql/DvxcgrvRJ52XNm8hERpoCcJ+ol3VmPL+g2C9btjGb6HglON0hiXKAN
F78cSv59OhBbOqbLzhx06XtlKbaxNigWBkQW3I4hAoGBAJnK9a6pGIRu1OgXQGyd
BBUYA9Hh/50CIUmLeC+aXh/vzzlngX/ez5wvNbxiygmjj8hSseiUjh1aMKX9u98e
yIc4n0amGzHR3c6X7J0L5d3sSedax49ETboUtrs2wgbiNdJkM0NXaAPNs+ctK1wE
FnN6u8IBdwKJbomkKODwnxYxAoGBAK2yzIvuskPK91tWMwv1nwAnXFFdtA9L5AN+
SuL1l36w5fb7IwSw4QYcfpqgnst0C2HVtsjzuahZ/R6FQZOvY7zRvwplSWD4DP58
af6piD0b2VPVWVb5jCRGjo2oaZOxFZmMqNmvVxv3SB+7Eeik9fEIsrpjUZOmyUQs
GMZH0FohAoGBANHXkYWRQKSJp02kmwJ1GZ/6905KnDOY9pjFEXTb657yYXvPb1tp
B8pVBwtsrXb6XT827Dpn3Rf/bitqwWwJuWwSc37C/6AavUHQGo1lm8+m86Imy4XJ
xOOhZIpmJocMSF9TBBYFLvJV+s3/1aXrnFPuc5rrh3A1jWtT/zN+lUON
-----END RSA PRIVATE KEY-----
frogcdcn
  • 391
  • 1
  • 4
  • 14
  • "It seems x509 cert request can only be generated by Openssl that Java has no control over that" is wrong for a start. The Java `keytool` can generate CSRs, for keypairs that are already in a keystore. The problem here appears to be that your .pem file doesn't contain a private key. – user207421 Jun 01 '15 at 01:45
  • 1
    Possible duplicate of [ProcessBuilder and running OpenSSL command which contains spaces](http://stackoverflow.com/q/30433917). Also, I believe you need `-newkey`. Otherwise, the existing key (if `bob.pem` exists) is in the wrong format. For the PEM formats, see [OpenSSL's rsautl cannot load public key created with PEM_write_RSAPublicKey](http://stackoverflow.com/q/30547646). You should `cat` the key `bob.pem` and offer it in the question, too. – jww Jun 01 '15 at 01:52
  • I think keystore is tied to Java, which is a limitation. BTW, I tried to replace another certificate with existing self-signed cert in keystore, but has to choose another alias. Is that possible to replace the self-signed certificate with a new cert? thanks. – frogcdcn Jun 01 '15 at 01:56
  • @frogdn If the new certificate is the CA-signed result of a CSR you should use the same alias you did when generating the CSR. As you're already using Java code, it isn't clear what the 'limitation' issue is. – user207421 Jun 01 '15 at 02:19
  • @jww If the .pem file contains the private key he should certainly **not** post it here in the question, and if it doesn't, it should. – user207421 Jun 01 '15 at 02:20
  • @jww, thanks. It's able to create key and cert request using openssl -newkey. Still, it would be nice for us to find out why openssl -new -key cannot work in command invoked by JVM. – frogcdcn Jun 01 '15 at 02:46
  • 2
    First things first: you have just compromised this private key, and should throw it away. You should use `exec(String[]),` not `exec(String).` The `keytool` is considerably *less* complex than the `openssl` command. – user207421 Jun 01 '15 at 02:56
  • @frogcdcn - the command works for me with the exemplary key you posted. I'm guessing it has to do with the way you are shelling out through the Java command (or the sample key is not exemplary of the key you are actually using). Like EJP said, shell out with a `String[]`. Make sure `arg[0]` is the name of the command (`openssl`), `arg[2]` is the subcommand (`req`), etc. `arg[0]` and the program name is very important. It should only be the program name. – jww Jun 01 '15 at 03:01
  • many thanks. It needs to use exec(String[]) rather than exec(String) to work. – frogcdcn Jun 01 '15 at 03:12
  • @jww, thanks for your advice. BTW, if openssl command is invoked in JVM, it is difficult to catch error. Though it's possible to get info using InputStream err=Process.getErrorStream(). "error", "unable" might be imprecise keywords to catch errors. – frogcdcn Jun 01 '15 at 10:41

2 Answers2

1

Use exec(String[]) rather than exec(String) to invoke Openssl command. A safe way is to list each argument in separate strings.

frogcdcn
  • 391
  • 1
  • 4
  • 14
0

You could always just put the openssl commands in a bash script, and then launch the bash script from your program like this

Process bash_script = Runtime.getRuntime().exec("/your/directory/openssl_script.sh");
apt-getschwifty
  • 199
  • 2
  • 12