0
votes

I am using Open SSL for RSA key pair generation and signing token with SHA1 Algorithm. Key pair generation was successfully done using OpenSSL and i got "PEM" certificate as result.

To proceed with signing process, i need DER formatted Private Key. If anyone knows, please share the code to convert PEM to DER certificates using openssl. I tried with terminal and it's working fine. But, i need the programmatic approach for this.

Following is my code to generate PEM certificate:

-(void)generateCertificate
{
    RSA *rsaKeyPair = NULL;
    rsaKeyPair = RSA_new();        

    BIGNUM *e = BN_new();
    BN_set_word(e, 65537);

    //Generating KeyPair
    RSA_generate_key_ex(rsaKeyPair, 1024, e, NULL);

    int keylen, keylenPub;
    char *pem_key, *pem_pub_key;

    /* To get the C-string PEM form: */
    BIO *bio = BIO_new(BIO_s_mem());
    BIO *bioPubKey = BIO_new(BIO_s_mem());        

    //Writing RSA Private and Public Keys        
    PEM_write_bio_RSAPrivateKey(bio, rsaKeyPair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(bioPubKey, rsaKeyPair);
    keylen = BIO_pending(bio);
    pem_key = calloc(keylen+1, 1); /* Null-terminate */
    BIO_read(bio, pem_key, keylen);

    //Reading RSA Public Key Bio        
    keylenPub = BIO_pending(bioPubKey);
    pem_pub_key = calloc(keylenPub+1, 1); /* Null-terminate */
    BIO_read(bioPubKey, pem_pub_key, keylenPub);            

    NSString *strData = [NSString stringWithUTF8String:pem_key];
    [strData writeToFile:[self privateKeyPath] atomically:YES encoding:NSUTF8StringEncoding error:nil];        

    NSString *strPubData = [NSString stringWithUTF8String:pem_pub_key];
    [strPubData writeToFile:[self publicKeyPath] atomically:YES encoding:NSUTF8StringEncoding error:nil];

    BIO_free_all(bio);
    RSA_free(rsaKeyPair);
}

And:

// Documents directory path
-(NSString *)privateKeyPath
{
    NSString *documentsFolder =   [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [documentsFolder stringByAppendingPathComponent:@"rsaprivkey.pem"];
 }

And:

-(NSString *)publicKeyPath
{
    NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [documentsFolder stringByAppendingPathComponent:@"rsapubkey.pem"];
}

And:

-(NSString *)derPrivateKeyPath
{
    NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [documentsFolder stringByAppendingPathComponent:@"rsaprivateKey.der"];
}

And:

#pragma mark - Signing section
-(NSData *)generateSignatureWithdataToSign :(NSData*)signableData
{
    BIO *in = BIO_new_file([[self derPrivateKeyPath] cStringUsingEncoding:NSUTF8StringEncoding], "rb");        

    PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in,NULL);

    EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
    NSLog(@"%i", p8inf->broken);
    PKCS8_PRIV_KEY_INFO_free(p8inf);
    BIO_free(in);
    uint8_t * cipherBuffer = NULL;

    // Calculate the buffer sizes.
    unsigned int cipherBufferSize = RSA_size(pkey->pkey.rsa);
    unsigned int signatureLength;

    // Allocate some buffer space. I don't trust calloc.
    cipherBuffer = malloc(cipherBufferSize);
    memset((void *)cipherBuffer, 0x0, cipherBufferSize);

    unsigned char *openSSLHash = SHA1(signableData.bytes, signableData.length, NULL);
    int success = RSA_sign(NID_sha1, openSSLHash, 20, cipherBuffer, &signatureLength, pkey->pkey.rsa);  //pkey->pkey.rsa
    if (success) NSLog(@"WIN");


    NSData *signatureData = [NSData dataWithBytes:(const void*)cipherBuffer length:signatureLength];

    EVP_PKEY_free(pkey);

    return signatureData;
}

Note: I want to get DER certificate from "rsaprivkey.pem" and write that DER to "rsaprivateKey.der" .. After that, i need to implement the signing process as coded above by using "rsaprivateKey.der" certificate...

1
Show us the code your are using so we can suggest what you should change.jww
I had updated my question with code which i had done so far.Please check thatuser3637181

1 Answers

2
votes

Finally, i found the answer to my question.. Following code may help others who all are stuck up with similar kind of issues....

-(void)generateCertificate
{
    const int kBits = 1024;
    const int kExp = 65537;

    int keylen, keylenPub;
    char *pem_key, *pem_key_pub;

    RSA *rsa = RSA_generate_key(kBits, kExp, 0, 0);



    EVP_PKEY *pkey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pkey, rsa);

     bioPriv = BIO_new(BIO_s_mem());

    //PKCS8 Encoded private Key

    i2d_PKCS8PrivateKey_bio(bioPriv, pkey, NULL, NULL, 0, NULL, NULL);


    keylen = BIO_pending(bioPriv);
    pem_key = calloc(keylen+1, 1);
    BIO_read(bioPriv, pem_key, keylen);

    printf("%s", pem_key);

    NSData *data = [NSData dataWithBytes:pem_key length:keylen];
    [data writeToFile:[self privateKeyPathDER] atomically:YES];



    //Public Key encryption and Saving

    bioPub = BIO_new(BIO_s_mem());
    i2d_RSA_PUBKEY_bio(bioPub, rsa);


    keylenPub = BIO_pending(bioPub);
    pem_key_pub = calloc(keylenPub+1, 1);
    BIO_read(bioPub, pem_key_pub, keylenPub);

    printf("%s", pem_key_pub);



    NSData *dataPub = [NSData dataWithBytes:pem_key_pub length:keylenPub];
   [dataPub writeToFile:[self publicKeyPathDER] atomically:YES];





    RSA_free(rsa);


}
#pragma mark - Signing section


-(NSData *)generateSignatureWithdataToSign :(NSData*)signableData
{

   //BIO *in = BIO_new_file([[self privateKeyPathDER] cStringUsingEncoding:NSUTF8StringEncoding], "rb");

    PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(bioPriv,NULL);

    EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
    NSLog(@"%i", p8inf->broken);
    PKCS8_PRIV_KEY_INFO_free(p8inf);
    BIO_free(bioPriv);



    uint8_t * cipherBuffer = NULL;

    // Calculate the buffer sizes.
    unsigned int cipherBufferSize = RSA_size(pkey->pkey.rsa);
    unsigned int signatureLength;

    // Allocate some buffer space. I don't trust calloc.
    cipherBuffer = malloc(cipherBufferSize);
    memset((void *)cipherBuffer, 0x0, cipherBufferSize);

    unsigned char *openSSLHash = SHA1(signableData.bytes, signableData.length, NULL);
    int success = RSA_sign(NID_sha1, openSSLHash, 20, cipherBuffer, &signatureLength, pkey->pkey.rsa);  //pkey->pkey.rsa
    if (success) NSLog(@"WIN");


    NSData *signatureData = [NSData dataWithBytes:(const void*)cipherBuffer length:signatureLength];

    EVP_PKEY_free(pkey);


    return signatureData;


}



-(NSString *)privateKeyPathDER
{
    NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [documentsFolder stringByAppendingPathComponent:@"rsaprivkey.der"];
}

-(NSString *)publicKeyPathDER
{
    NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [documentsFolder stringByAppendingPathComponent:@"rsapubkey.der"];
}