Well, to roll out the possibility of network error's, JSON values not being passed properly and blah blah blah I just dropped that approach. instead of that I am running C program which prints the prime,generator and public key. I have another program on same machine which is written in java where I am hard coding these C generated values and trying to get the public and secret key. ofcourse it is also giving me the same exception.
below is the complete C code written to generate DH params. most of the part is taken from openSSL library source code. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/crypto.h> #include <openssl/dh.h> #include <err.h> static const char rnd_seed[] = "string to make the random number generator think it has the entropy"; int main(){ BN_GENCB _cb; DH *client= NULL; char buf[12]; unsigned char *clientbuf=NULL; int i,clientlen,clientout,ret=1; BIO *out; CRYPTO_malloc_debug_init(); CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); ERR_load_crypto_strings(); #ifdef OPENSSL_SYS_WIN32 CRYPTO_malloc_init(); #endif RAND_seed(rnd_seed, sizeof rnd_seed); out=BIO_new(BIO_s_file()); if (out == NULL) { printf("BIO is null. exiting from program"); goto err; } BIO_set_fp(out,stdout,BIO_NOCLOSE); //BN_GENCB_set(&_cb,&cb, out);//is this really required. my gcc not recognizing cb instance so just commenting client = DH_new(); if(client == NULL){ printf("Client DH is null"); goto err; } DH_generate_parameters_ex(client,1024,DH_GENERATOR_5,NULL); if (!DH_check(client, &i)) { goto err; } if (i & DH_CHECK_P_NOT_PRIME) BIO_puts(out, "p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) BIO_puts(out, "p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) BIO_puts(out, "unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) BIO_puts(out, "the g value is not a generator\n"); BIO_puts(out,"\np=");//this prints the P in hex printf("%s",BN_bn2dec(client->p));//this prints the P in decimal BIO_puts(out,"\ng="); BN_print(out,client->g);//prints generator which is 5 in this case BIO_puts(out,"\n"); if (!DH_generate_key(client)) { printf("unable to generate client keys"); goto err; } BIO_puts(out,"pri 1="); BN_print(out,client->priv_key);//prints private key BIO_puts(out,"\npub 1="); printf("%s",BN_bn2dec(client->pub_key));//prints public key in decimal format DH *temp = DHparams_dup(client); BIO_puts(out,"\n\n\n PEM = "); PEM_write_bio_DHparams(out, temp);//this prints public key in base64 (this is what i think :) ) BIO_puts(out,"\n\n"); err: if (clientbuf != NULL) OPENSSL_free(clientbuf); if (serverbuf != NULL) OPENSSL_free(serverbuf); if(server != NULL) DH_free(server); if(client != NULL) DH_free(client); BIO_free(out); return 1; } This is what it prints when I ran this program. p=106824077746282794452228647025839229808074839339760371103063155402464842614962676228255294325459053774613506891207056818441720848774298482866918174271328357364028843638451324415691330056638482781344307395975948664971732094293996189467599104442989563027727348339786810653279203313302815966250977426622843204103 g=5 pri1=622BBB2CA70FC8665F9EC3A95CF7B5C46D2F77AB10AA7D3FF485ADA9C6E005C7CF35AC0DBBFC256D2EB3AC702899140369433E1546B9DC915ACA5883D91F8FACB731F745B23C3A399FAFBDC6355E3D4203462432E950670297F6930B98C261A215053164893C2FAB55A1170699C3EDE919E59F895455B995A19C37670A6FA358 pub1=4373485839237796166699589228729451887524557806298817546317652313209684941935291316056752499275686842785989445002203537603465313281932431907074220666705812428468899520395399424699433568818334649395647035588736697462362131440308900155995886437558059484184376957451229991382889256903754886307405909744230582829 PEM = -----BEGIN DH PARAMETERS----- MIGHAoGBAJgfXoi5POaY+aWtOFfykV7i9JNaX1ecr1W/PeqNwpcdTg1y75FaJwrO LZSKds6dr6HtTEs5Jltda1GY2HklY8f3mja5EhNeLGLRfchQ8+Bn2FPGU1mMFpbF 07/tRJe6SOLfbQzIcTLn+TXbkS5fKWqerRnww4NZI0B+FBC+/DIHAgEF -----END DH PARAMETERS----- Here is my java code . import java.io.*; import java.math.BigInteger; import java.security.*; import java.security.spec.*; import java.security.interfaces.*; import javax.crypto.*; import javax.crypto.spec.*; import javax.crypto.interfaces.*; import com.sun.crypto.provider.SunJCE; public class DiffieHellmanServer { private DiffieHellmanServer() { }; public static void main(String argv[]) { try { DiffieHellmanServer keyAgree = new DiffieHellmanServer(); keyAgree.run1(); } catch (Exception e) { System.err.println("Error: " + e); System.exit(1); } } private void run1() throws Exception { DHParameterSpec dhSkipParamSpec; /** using C passed hard coded parameters*/ dhSkipParamSpec = new DHParameterSpec(skip1024Modulus,skip1024Base, 1024); /* Instead of base64,Even I tried with passing HEX and DECIMAL values as a client public key and then converting them into byte[]. didn't work */ byte[] clientPubKeyEnc =new sun.misc.BASE64Decoder().decodeBuffer("MIGHAoGBAJgfXoi5POaY+aWtOFfykV7i9JNaX1ecr1W/PeqNwpcdTg1y75FaJwrO"+ "LZSKds6dr6HtTEs5Jltda1GY2HklY8f3mja5EhNeLGLRfchQ8+Bn2FPGU1mMFpbF"+ "07/tRJe6SOLfbQzIcTLn+TXbkS5fKWqerRnww4NZI0B+FBC+/DIHAgEF"); KeyFactory bobKeyFac = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(clientPubKeyEnc); PublicKey alicePubKey = bobKeyFac.generatePublic(x509KeySpec); //*this throws invalidKeySpecException : invalid key specification * /* * Bob gets the DH parameters associated with Alice's public key. He * must use the same parameters when he generates his own key pair. */ DHParameterSpec dhParamSpec = ((DHPublicKey) alicePubKey).getParams(); /** Bob creates his own DH key pair */ KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH"); bobKpairGen.initialize(dhParamSpec); KeyPair bobKpair = bobKpairGen.generateKeyPair(); /** Bob creates and initializes his DH KeyAgreement object */ KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); bobKeyAgree.init(bobKpair.getPrivate()); /** Bob encodes his public key, and sends it over to Alice. */ byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded(); bobKeyAgree.doPhase(alicePubKey, true); byte[] bobSharedSecret = bobKeyAgree.generateSecret(); /** print down Bob's shared key */ bobKeyAgree.doPhase(alicePubKey, true); SecretKey bobDesKey = bobKeyAgree.generateSecret("DES"); byte[] encodedKeybob = bobDesKey.getEncoded(); System.out.println(new BigInteger(encodedKeybob)); } private static final BigInteger skip1024Modulus = new BigInteger( "106824077746282794452228647025839229808074839339760371103063155402464842614962676228255294325459053774613506891207056818441720848774298482866918174271328357364028843638451324415691330056638482781344307395975948664971732094293996189467599104442989563027727348339786810653279203313302815966250977426622843204103"); /** The base used with the SKIP 1024 bit modulus */ private static final BigInteger skip1024Base = BigInteger.valueOf(5); } Regards, Azhar On Tue, Mar 19, 2013 at 4:53 PM, Matt Caswell <fr...@baggins.org> wrote: > On 19 March 2013 10:37, azhar jodatti <azhar...@gmail.com> wrote: > > > > > > On Tue, Mar 19, 2013 at 2:58 PM, Matt Caswell <fr...@baggins.org> wrote: > >> > >> On 19 March 2013 09:01, azhar jodatti <azhar...@gmail.com> wrote: > >> > >> > And possibly relevant here, the standard Suncle JCE provider actually > >> > uses DSA paramgen for DH and thus imposes the DSA size restrictions > >> > on DH -- 512 to 1024 in steps of 64 -- although they aren't required > >> > by any standard I know of. I don't recall if JCE also restricts > >> > *existing* (received) params; I'll test when I have some time. > >> > I do recall you can get around this by using BouncyCastle instead. > >> > But just using 1024 is easy and fine. > >> > --> > >> > > >> > sometime I get below error "Prime size must be multiple of 64, and can > >> > only range from 512 to 1024 (inclusive)" > >> > when i use small prime numbers.It means JCE uses DSA paramateres for > DH > >> > algorithm. what is openSSL equalent to this? > >> > > >> > KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); > >> > kpg.initialize(1024); > >> > keyPair = kpg.generateKeyPair(); > >> > > >> > DHParameterSpec dhSpec = ((DHPublicKey) > >> > keyPair.getPublic()).getParams(); > >> > baseGenerator = dhSpec.getG(); > >> > prime = dhSpec.getP(); > >> > sizeInBits = dhSpec.getL(); > >> > is this java code equalent to below c code? > >> > DH_generate_parameters_ex(client,1024,DH_GENERATOR_5,NULL); > >> > > >> > see, with openSSL I have to pass DH_GENERATOR which only allowes (2 > and > >> > 5) but that is not required in JAVA version.It generates it own base > >> > generator. > >> > >> It appears to be equivalent, although I am not familiar with the JCE > >> API. What I do not understand though is why you have code to generate > >> parameters on *both* sides of your communication. If you are going to > >> generate params every time (which both Dave and myself have advised > >> against - it is an expensive operation), you still only need to do it > >> on one side of the communication. So, after a bit of googling, I > >> would expect to see something like this on the Java side (if the C > >> side generates the params): > > > > > > Well, above both the code snaps are at client side, not at server. I > > understand I don't have to generate keys at both the end. I just wanted > to > > give you an idea how I am doing it in JAVA and C to generate the keys. As > > you said both code appears to be equivalent but practically it won't > seems > > like . at-least in my scenario. because parameters generated with above > java > > code works with my server but that's not the case with parameters > generated > > with above C code. > > > >> > >> > >> KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); > >> kpg.initialize(new DHParameterSpec(/* p value passed from C */, /* g > >> value passed from C */)); > >> keyPair = kpg.generateKeyPair(); > >> > > yes, I m doing this at server. after generating keyPair I am generating > > keyAgreent as well > > . below is the code for this > > > > KeyAgreement keyAgree = KeyAgreement.getInstance("DH"); > > keyAgree.init(keyPair.getPrivate()); > > //this generates public key at server > > byte[] serverPubKeyEnc = keyPair.getPublic().getEncoded(); > > //I really don't know how exactly it does this. but its mandatory > > keyAgree.doPhase(clientPubllicKey, true); > > //this generates secret key at server > > byte[] sharedSecret = keyAgree.generateSecret(); > > > Can you share the code where you load the parameters from the C into > JCE? Also how you set up clientPublicKey. Finally would be useful if > you can dump out the parameters after they have been read, and compare > to the JSON sent. > > Matt >