Getting private key from file in java - java

I have private key file with "key" extension.I know that is generated by "Admin-PKI" programm.I must read it as object of PrivateKey type in java to use it for digital signature generation.I tried open it in text editor,but there are not header and footer such as "begin private key" and "end private key".How can i know what algorithm was used to generate the private key?Can i do this without knowing algorithm?

the code below loads a file key.pem, you will need the bouncycastle library (http://bouncycastle.org/)
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyPair;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
public class LoadKey {
public static void main(String [] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyPair keyPair = readKeyPair(new File("key.pem"));
}
private static KeyPair readKeyPair(File privateKey) throws IOException {
FileReader fileReader = new FileReader(privateKey);
PEMReader r = new PEMReader(fileReader);
try {
return (KeyPair) r.readObject();
} catch (IOException ex) {
throw new IOException("The private key could not be decrypted", ex);
} finally {
r.close();
fileReader.close();
}
}
}
compile and run with
javac -cp bcprov-jdk16-146.jar:. LoadKey.java
java -cp bcprov-jdk16-146.jar:. -ea LoadKey

Related

Regeneration of SecretKey results in different key in java

I am trying to create an Encryption Program. However, The problem is when I am trying to Regenerate the SecretKey, I get different key which is not the same as the encryption key.
Here is my code snippet which I am using for testing purpose.`
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.util.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
class Test
{
static void My_Get_Key() throws Exception
{
String temp;
File f=new File("/home/mandar/Desktop/key.txt");
Scanner sc=new Scanner(f);
temp=sc.nextLine();
byte[] sk=Base64.decode(temp);
//byte[] sk=temp.getBytes();
//byte[] sk=temp.getBytes(StandardCharsets.ISO_8859_1);
SecretKey OriginalKey=new SecretKeySpec(sk,0,sk.length,"AES");
System.out.println("Decrypt Key is "+OriginalKey.toString());
//return OriginalKey;
}
static void My_Key_Generate() throws Exception
{
KeyGenerator key=KeyGenerator.getInstance("AES");
key.init(128);
SecretKey sk=key.generateKey();
System.out.println("Encrypt Key is "+sk.toString());
BufferedWriter wt = new BufferedWriter(new FileWriter("/home/mandar/Desktop/key.txt"));
String KeyString =sk.toString();
byte[] bytekey= KeyString.getBytes();
String WriteKey= Base64.encode(bytekey);
wt.write(sk.toString());
wt.flush();
wt.close();
//return sk;
}
public static void main(String[] args) throws Exception
{
My_Key_Generate();
My_Get_Key();
}
}
please Help.
PS: I am trying to store the generated key by converting it into string and writing it into a file and using the same file to retrieve the string and regenerate the key again.
The problem is that "sk.toString()" does not provide the contents of the key.
You need to call "sk.getEncoded()". Please note that it will return a byte array, not an String.
Write the contents of that byte array to the file and read it back.
Try with this modified code that uses "getEncoded()":
import java.util.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
class Test {
static void My_Get_Key() throws Exception {
byte[] sk = Files.readAllBytes(Paths.get("/home/mandar/Desktop/key.txt"));
SecretKey OriginalKey = new SecretKeySpec(sk, 0, sk.length, "AES");
System.out.println("Decrypt Key is " + Arrays.toString(OriginalKey.getEncoded()));
}
static void My_Key_Generate() throws Exception {
KeyGenerator key = KeyGenerator.getInstance("AES");
key.init(128);
SecretKey sk = key.generateKey();
System.out.println("Encrypt Key is " + Arrays.toString(sk.getEncoded()));
Files.write(Paths.get("/home/mandar/Desktop/key.txt"), sk.getEncoded());
}
public static void main(String[] args) throws Exception {
My_Key_Generate();
My_Get_Key();
}
}

Java 8 cannot load its cacerts in FIPS. Exception "no such provider: SunEC"

My server was using java 7 and is running fine in FIPS mode. Now we are upgrading to jre8 and the following exception is coming during the startup while loading cacerts.
java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC
at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
at sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
at sun.security.pkcs11.P11ECKeyFactory.engineGeneratePublic(P11ECKeyFactory.java:170)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
at sun.security.x509.X509Key.parse(X509Key.java:170)
at sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
at java.security.KeyStore.load(KeyStore.java:1433)
at org.apache.commons.ssl.KeyStoreBuilder.tryJKS(KeyStoreBuilder.java:476)
at org.apache.commons.ssl.KeyStoreBuilder.parse(KeyStoreBuilder.java:383)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:212)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:165)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:170)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:175)
at org.apache.commons.ssl.TrustMaterial.<clinit>(TrustMaterial.java:88)
at org.opensaml.xml.security.x509.X509Util.decodeCertificate(X509Util.java:317)
Caused by: java.security.NoSuchProviderException: no such provider: SunEC
at sun.security.jca.GetInstance.getService(GetInstance.java:83)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
at java.security.KeyFactory.getInstance(KeyFactory.java:211)
at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)
The only modification i made is to add TLSv1.2 to jdk.tls.disabledAlgorithms=SSLv3,TLSv1.2 since NSS is not supporting TLSv1.2.
I was able to load the same in jre7u72 builds and i see that the sunpkcs11.jar is modified in java 8. It shouldnt be a cacerts issue since i copied the java7 cacerts to java8 and the problem still remains.
Has anyone seen this issue before? Should it be a java bug?
=== EDIT ===
Opened a java 8 bug. I wrote a tool which ran against jre7 with success and failed with jre8.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.security.provider.Sun;
import sun.security.rsa.SunRsaSign;
/**
* Before running the tool run the following in your Linux box.
*
1. export LD_LIBRARY_PATH=/usr/lib64
2. mkdir /tmp/fips/nssdb
3. modutil -create -dbdir /tmp/fips/nssdb/
4. modutil -fips true -dbdir /tmp/fips/nssdb
5. modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /tmp/fips/nssdb
(Give a strong password like password1!)
* #author atulsm#gmail.com
*
*/
public class TestKeyStoreFIPS {
public static final String NSS_LIB_DIR_PROP = "nss.lib";
public static final String NSS_DB_DIR_PROP = "nss.db";
public static final String SUN_JSSE = "SunJSSE";
public static List<String> disabledAlgs = new ArrayList<String>();
private static final Logger logger = Logger.getLogger(TestKeyStoreFIPS.class.getName());
/**
* #param args
*/
public static void main(String[] args) throws Exception{
if(args.length != 2){
System.out.println("Usage eg: java -Dnss.lib=/usr/lib64 -Dnss.db=/tmp/fips/nssdb -Djavax.net.ssl.keyStorePassword=password1! TestKeyStoreFIPS /tmp/jre8/lib/security/cacerts changeit");
System.exit(1);
}
enablePkcs11Jsse(System.getProperty(NSS_LIB_DIR_PROP), System.getProperty(NSS_DB_DIR_PROP));
testFips();
String file = args[0];
char[] keystorePassword = args[1].toCharArray();
FileInputStream keystoreStream = new FileInputStream(file);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keystoreStream, keystorePassword);
Enumeration<String> aliases = keyStore.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
System.out.println(alias + " : " + keyStore.getCertificate(alias).getType());
}
}
private static void testFips(){
String keyPass = System.getProperty("javax.net.ssl.keyStorePassword");
KeyStore store;
try {
store = KeyStore.getInstance("PKCS11");
if (keyPass != null) {
store.load(null, keyPass.toCharArray());
} else {
store.load(null, null);
}
System.out.println("FIPS test success");
} catch (Throwable e) {
e.printStackTrace();
store = null;
System.out.println("FIPS test failed");
}
}
public static void enablePkcs11Jsse( String libDir, String dbDir) throws Exception {
removeAllProviders();
Provider nss = getNSSFIPSProvider( libDir, dbDir);
removeDisabledAlgos(nss);
Security.insertProviderAt(nss, 1);
Provider sunJsse = new com.sun.net.ssl.internal.ssl.Provider(nss);
removeDisabledAlgos(sunJsse);
Security.insertProviderAt(sunJsse,2);
Sun sun = new Sun();
removeDisabledAlgos(sun);
Security.insertProviderAt(sun,3);
SunRsaSign sunrsa = new SunRsaSign();
removeDisabledAlgos(sunrsa);
Security.insertProviderAt(sunrsa,4);
}
private static Provider getNSSFIPSProvider( String libDir, String dbDir) throws Exception {
if(libDir == null || dbDir == null) {
throw new Exception(NSS_LIB_DIR_PROP + " or " + NSS_DB_DIR_PROP + " not set.");
}
Properties props = new Properties();
props.put("name", "NSSfips");
props.put("nssLibraryDirectory", libDir);
props.put("nssSecmodDirectory", dbDir);
props.put("nssModule", "fips");
props.put("nssDbMode", "readWrite");
return createProvider(props);
}
private static Provider createProvider(Properties props) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
props.store(out, null);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Provider ret = new sun.security.pkcs11.SunPKCS11(in);
if (logger.isLoggable(Level.FINE)) {
// Log all of the registered services
for (Map.Entry<Object, Object> entry : ret.entrySet()) {
logger.log(Level.FINE, "{0} = {1}", new Object[]{entry.getKey(), entry.getValue()});
}
}
return ret;
}
private static void removeAllProviders(){
Provider[] providers = Security.getProviders();
for(Provider prov : providers){
Security.removeProvider(prov.getName());
}
}
private static void removeDisabledAlgos(Provider provider){
for(String alg : disabledAlgs){
if(provider.getProperty(alg) != null){
logger.info("Removing algorithm " + alg + " from provider " + provider);
provider.remove(alg);
}
}
}
}
While i explore other options, one approach which worked is to copy one of my truststores as jre/lib/security/jssecacerts. I see that the code is giving precedence to jssecacerts than cacerts and its working fine for now.

OpenID Connect (JWS): Using client secret as HMACSHA-256 key for verifying ID Token

I'm implementing OpenID Connect code flow, and I'm a bit confused on how to use the client secret as a key when using javax.crypto.Mac for generating the HMACSHA-256 signature. I can't figure out how to convert the client ID to key bytes.
import org.apache.commons.codec.Charsets;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class HMACSigner {
public static final String HMACSHA256 = "HmacSHA256";
public String createSignature(final String messageToSign, final String clientSecret) {
// How do I convert the client secret to the key byte array?
SecretKeySpec secretKey = new SecretKeySpec(clientSecret.getBytes(Charsets.UTF_8), HMACSHA256);
try {
Mac mac = Mac.getInstance(HMACSHA256);
mac.init(secretKey);
byte[] bytesToSign = messageToSign.getBytes(Charsets.US_ASCII);
byte[] signature = mac.doFinal(bytesToSign);
return Base64.encodeBase64URLSafeString(signature);
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
}
}
Following the example at https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-signature-17#appendix-A, I've created the following test case. My output is ZekyXWlxvuCN9H8cuDrZfaRa3pMJhHpv6QKFdUqXbLc.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class HMACSignerTest {
private HMACSigner sut;
#Test
public void should_create_signature_according_to_spec() {
sut = new HMACSigner();
String signature = sut.createSignature("eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow");
assertEquals("dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", signature);
}
}
The key seems to be Base64 encoded:
SecretKeySpec secretKey = new SecretKeySpec(Base64.decodeBase64(clientSecret), HMACSHA256);

Piping PrintWriter->CipherOutputStream->FileOutputStream

Here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class EncryptedLogger {
private static Date lastLogTime = null;
private static EncryptedLogger instance = null;
private static FileOutputStream fos = null;
private static CipherOutputStream cos = null;
private static PrintWriter writer = null;
private Cipher cipher;
byte[] Key ={(byte) 0x12,(byte) 0x34,0x55,(byte) 0x66,0x67,(byte)0x88,(byte)0x90,0x12,(byte) 0x23,0x45,0x67,(byte)0x89,0x12,0x33,(byte) 0x55,0x74};
public static EncryptedLogger getInstance(){
if (instance==null) {
instance = new EncryptedLogger();
}
return instance;
}
private EncryptedLogger(){
class SQLShutdownHook extends Thread{
#Override
public void run() {
EncryptedLogger.close();
super.run();
}
}
SecretKeySpec sks = new SecretKeySpec(Key,"AES");
try {
cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,sks);
fos = new FileOutputStream(new File("log.txt"),true);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
cos = new CipherOutputStream(fos, cipher);
writer = new PrintWriter(cos);
SQLShutdownHook hook = new SQLShutdownHook();
Runtime.getRuntime().addShutdownHook(hook);
}
public synchronized void logSQL(String s){
if ((lastLogTime==null)||((new Date().getTime() -lastLogTime.getTime())>1000)){
lastLogTime = new Date();
writer.printf("-- %1$tm-%1$te-%1$tY %1$tH-%1$tM-%1$tS\n%2$s\n",new Date(),s);
}
else{
writer.println(s);
}
}
public synchronized void logComment(String s){
writer.printf("-- %1$tm-%1$te-%1$tY %1$tH-%1$tM-%1$tS: %2$s\n",new Date(),s);
}
public static void close(){
writer.flush();
writer.close();
}
public static void main(String[] args) throws InterruptedException {
EncryptedLogger.getInstance().logSQL("1");
EncryptedLogger.getInstance().logSQL("22");
EncryptedLogger.getInstance().logSQL("33333");
EncryptedLogger.getInstance().logSQL("4900");
EncryptedLogger.getInstance().logSQL("5");
EncryptedLogger.getInstance().logSQL("66666");
EncryptedLogger.getInstance().logSQL("Some test logging statement");
EncryptedLogger.getInstance().logSQL("AAAAAAAAAAAAAAAAAAAAAAAAAA");
EncryptedLogger.getInstance().logComment("here is test commentary");
}
}
As you see i'm trying to encrypt text entries piping them through PrintWriter->CipherOutputStream->FileOutputStream chain. But when I decrypt result file there are missing bytes. I tried to flush cos and fos in EncryptedLogger.close() method - same result. Obviously i'm missing something. What is wrong?
EDIT: here is decryption code i use. It's not mine, taken from tutorial or something...
And it works fine when using simmilar encryption. But when using my code...
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESDecrypter
{
Cipher dcipher;
public AESDecrypter(SecretKey key)
{
try
{
dcipher = Cipher.getInstance("AES");
dcipher.init(Cipher.DECRYPT_MODE, key);
}
catch (Exception e)
{
e.printStackTrace();
}
}
byte[] buf = new byte[1024];
public void decrypt(InputStream in, OutputStream out)
{
System.out.println("decrypting");
try
{
in = new CipherInputStream(in, dcipher);
int numRead = 0;
while ((numRead = in.read(buf)) >= 0)
{
out.write(buf, 0, numRead);
}
out.close();
}
catch (java.io.IOException e)
{
}
}
public static void main(String args[])
{
try
{
byte[] keystr ={(byte) 0x12,(byte) 0x34,0x55,(byte) 0x66,0x67,(byte)0x88,(byte)0x90,0x12,(byte) 0x23,0x45,0x67,(byte)0x89,0x12,0x33,(byte) 0x55,0x74};
SecretKeySpec sks = new SecretKeySpec(keystr,"AES");
AESDecrypter encrypter = new AESDecrypter(sks);
encrypter.decrypt(new FileInputStream("sqllogenc.log"),new FileOutputStream("sqllogdec.log"));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
EDIT2: when i write directly to fos i get this output:
-- 04-19-2012 16-17-56
1
22
33333
4900
5
66666 + delay starting 1100
Some test logging statement
AAAAAAAAAAAAAAAAAAAAAAAAAA
-- 04-19-2012 16-17-56: here is test commentary
and when writing using cos and decrypting:
-- 04-19-2012 16-22-13
1
22
33333
4900
5
66666 + delay starting 1100
Some test logging statement
AAAAAAAAAAAAAAAAAAAAAAAAAA
-- 04-19-2012 16-22-13: here
As you see part of the last line is missing including linebreak.
You should use the same cryptographic transformation (such as AES/ECB/NoPadding) at both sides. Also, note that NoPadding mode doesn't allow you to pass data of arbitrary size, therefore you need to specify some other kind of padding.
So, you need to construct Ciphers as Cipher.getInstance("AES/ECB/PKCS5Padding") at both sides.
Also, note the suggestion of rossum about use of CBC or CTR instead of ECB.
Well, AES has a fixed block size of 128 bits.
When you use AES/ECB/NoPadding, you take the responsability of making sure the size of your message is a multiple of the block size.
It probably isn't, so you get less text when you decrypt.
You should use AES/ECB/NoPadding for arbitrary length of text.

How to correctly encode DH parameters using BouncyCastle in Java?

I am trying to reproduce the output of "openssl dhparam -out dh1024.pem 1024" command programatically in Java. The code snippet is following:-
DHParametersGenerator generator = new DHParametersGenerator();
generator.init(1024, 0, new SecureRandom());
DHParameters params = generator.generateParameters();
// Generator G is set as random in params, but it has to be 2 to conform to openssl
DHParameters realParams = new DHParameters(params.getP(), BigInteger.valueOf(2));
byte[] p = realParams.getP().toByteArray();
byte[] g = realParams.getG().toByteArray();
byte[] l = new byte[(byte) realParams.getL()];
byte[] pgl = new byte[p.length+g.length+l.length];
System.arraycopy(p, 0, pgl, 0, p.length);
System.arraycopy(g, 0, pgl, p.length, g.length);
System.arraycopy(l, 0, pgl, p.length+g.length, l.length);
So basically I am concatenating the values of P,G and L parameters in a byte array "pgl" and then saving it in a file using the PEMWriter class from BC. But when I try to use it via openssl, I get the following error:-
Cannot load DH parameters from
/etc/openvpn/easy-rsa/keys/dh1024.pem:
error:0D07207B:asn1 encoding
routines:ASN1_get_object:header too
long: error:0D068066:asn1 encoding
routines:ASN1_CHECK_TLEN:bad object
header: error:0D07803A:asn1 encoding
routines:ASN1_ITEM_EX_D2I:nested asn1
error: error:0906700D:PEM
routines:PEM_ASN1_read_bio:ASN1 lib
.... which leads me to believe that I am encoding the DH Parameters wrongly, but I cannot find anywhere the correct way to encode this. Can anyone help me in this? I've been bouncing my head against the castle wall fro many days now but to no avail .... please help :(
Here is an example. Note that you cannot set the certainty argument to 0 in generator.init() or you won't get a prime! Most of this code I figured out just by looking at the Bouncycastle source code, for example look at the PEMWriter class.
import java.math.BigInteger;
import java.security.SecureRandom;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.crypto.generators.DHParametersGenerator;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.util.encoders.Base64;
public class OpenSSLDHParamClone
{
public static void main(String[] args) throws Exception
{
DHParametersGenerator generator = new DHParametersGenerator();
generator.init(1024, 80, new SecureRandom());
DHParameters params = generator.generateParameters();
// Generator G is set as random in params, but it has to be 2 to conform to openssl
DHParameters realParams = new DHParameters(params.getP(), BigInteger.valueOf(2));
ASN1EncodableVector seq = new ASN1EncodableVector();
seq.add(new DERInteger(realParams.getP()));
seq.add(new DERInteger(realParams.getG()));
byte [] derEncoded = new DERSequence(seq).getDEREncoded();
System.out.println("-----BEGIN DH PARAMETERS-----");
String b64Encoded = new String(Base64.encode(derEncoded), "US-ASCII");
while (b64Encoded.length() > 0) {
int subStringLength = Math.min(64, b64Encoded.length());
System.out.println(b64Encoded.substring(0, subStringLength));
b64Encoded = b64Encoded.substring(subStringLength);
}
System.out.println("-----END DH PARAMETERS-----");
}
}
Thanks GregS, your solution works but I eventually solved it using standard Java plus PemWriter from BC, although you cannot set the Generator G = 2 with this approach, but its still works both with openssl and Java, which was my initial purpose anyway :)
import java.io.FileWriter;
import java.io.IOException;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
public class DHCredentials {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, IOException
{
DHCredentials dhc = new DHCredentials();
System.out.println("This may take a long time ...");
dhc.saveDHParams("C:\\xxxDH.txt", dhc.genDHParams());
System.out.println("Done");
}
public byte[] genDHParams() throws IOException
{
AlgorithmParameterGenerator paramGen = null;
try
{
paramGen = AlgorithmParameterGenerator.getInstance("DH");
paramGen.init(1024, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
AlgorithmParameters params = paramGen.generateParameters();
return params.getEncoded();
}
public void saveDHParams(String filePath, byte[] DEREncodedDHParams)
{
PemWriter pemWrt;
try {
pemWrt = new PemWriter(new FileWriter(filePath));
pemWrt.writeObject(new PemObject("DH PARAMETERS", DEREncodedDHParams));
pemWrt.flush();
pemWrt.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Categories

Resources