​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
>

Reply via email to