Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
smiley
Posts: 1,466
Registered: ‎07-14-2008
My Device: Z10
My Carrier: Fido
Accepted Solution

How to create RAS Keys?

Try to generate the public and private keys pairs.

 

I have the following.  Just not sure if this correct and how to get the public and private keys out of the param.

 

		int rc = hu_RSAParamsCreate(512, rngctx, NULL, &rsaParams, globalContext.ctx());
		if (rc == SB_SUCCESS)
		{
			rc = hu_RSAKeyGen(rsaParams, 0, NULL, &privateKey, &publicKey, globalContext.ctx());
			if (rc == SB_SUCCESS)
			{
				size_t eLen = 512;
				unsigned char pubkey[512], prikey[512];

				memset(&pubkey, 0, 512);
				memset(&prikey, 0, 512);

				rc = hu_RSAKeyGet(
				    rsaParams,
				    privateKey,
				    publicKey,
				    &eLen,
				    (unsigned char *)&pubkey,
				    NULL,
				    NULL,
				    &eLen,
				    (unsigned char *)&prikey,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    NULL,
				    globalContext.ctx()
				);
				if (rc == SB_SUCCESS)
				{
					qDebug() << "public" << pubkey << "len" << QString::number(eLen);
					qDebug() << "private" << prikey;
				}

			}

		}

 the output for the pubkey size is only 3 bytes.

 

 

Please use plain text.
BlackBerry Development Advisor (Retired)
robbieDubya
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: How to create RAS Keys?

[ Edited ]

Hi,

 

e is normally 65536 - which fits into 3 bytes - that's why you're seeing the 3.

 

For RSA private keys - you generally keep / pass around all of the numbers, d,p,q, etc. Some of them can seem redundant - but knowing them makes your calculations faster.

 

For public - you only need both d & e.

 

How are you planning on using the key? In App, or shared?

 

I did have a sample showing how to use OpenSSL to encode the RSA key pair - but I cannot find it - wiill have to rebuild...

 

 

 

 

 

 

--
Rob is no longer associated with BlackBerry.
Please use plain text.
Developer
smiley
Posts: 1,466
Registered: ‎07-14-2008
My Device: Z10
My Carrier: Fido

Re: How to create RAS Keys?


robbieDubya wrote:

Hi,

 

e is normally 65536 - which fits into 3 bytes - that's why you're seeing the 3.

 

For RSA private keys - you generally keep / pass around all of the numbers, d,p,q, etc. Some of them can seem redundant - but knowing them makes your calculations faster.

 

For public - you only need both d & e.

 

How are you planning on using the key? In App, or shared?

 

I did have a sample showing how to use OpenSSL to encode the RSA key pair - but I cannot find it - wiill have to rebuild...

 


I have used a different lib many years ago  which let me export both public and private keys to a file.

 

so I do I get the keys?

 

I'm planning to use this in my app to send public key to other users.

 

If you have code example that would be great. thanks

Please use plain text.
BlackBerry Development Advisor (Retired)
robbieDubya
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: How to create RAS Keys?

Hi,

 

Here's one way to generate an RSA keypair, then encode the parts with OpenSSL.

 

The principal is easy.

  • get all of the numbers from the key pair
  • convert them to openSSL numbers
  • encode an RSA key

The sample doesn't do anything else with the keys - just tidies up after itself...

 

void dump(BUF_MEM * buf) {
	std::cout.write(buf->data, buf->length);
	std::cout << std::endl;
}

void zero(size_t ** s) {
	while (*s != NULL) {
		**s = 0;
		++s;
	}
}

void allocate(size_t ** s, unsigned char *** c) {
	while (*s != NULL && *c != NULL) {
		**c = new unsigned char[**s];
		++s;
		++c;
	}
}

void toBN(size_t ** s, unsigned char *** c, BIGNUM *** b) {
	while (*s != NULL && *c != NULL && *b != NULL) {
		**b = BN_bin2bn(**c, **s, NULL);

		++s;
		++c;
		++b;
	}
}

void destroy(unsigned char *** c) {
	while (*c != NULL) {
		if (**c != NULL) {
			delete[] **c;
		}
		++c;
	}
}

void destroy(BIGNUM *** b) {
	while (*b != NULL) {
		BN_free(**b);
		**b = NULL;
		++b;
	}
}

void rsaGenerateAndExport(DRBG & rand, GlobalContext &globalContext) {
	sb_Params rsaParams(NULL);
	sb_PrivateKey privateKey(NULL);
	sb_PublicKey publicKey(NULL);

	int rc = hu_RSAParamsCreate(512, rand.ctx(), NULL, &rsaParams,
			globalContext.ctx());
	if (rc != SB_SUCCESS) {
		qDebug() << "Could not create RSA params" << SBError::getErrorText(rc);
	} else {
		rc = hu_RSAKeyGen(rsaParams, 0, NULL, &privateKey, &publicKey,
				globalContext.ctx());
		if (rc != SB_SUCCESS) {
			qDebug() << "Could not generate RSA key"
					<< SBError::getErrorText(rc);
		} else {
			size_t eLen, nLen, dLen, pLen, qLen, dModPLen, dModQLen, qInvLen;

			size_t * sizes[] = { &eLen, &nLen, &dLen, &pLen, &qLen, &dModPLen,
					&dModQLen, &qInvLen, NULL };
			zero(sizes);

			rc = hu_RSAKeyGet(rsaParams, privateKey, publicKey, &eLen, NULL,
					&nLen, NULL, &dLen, NULL, &pLen, NULL, &qLen, NULL,
					&dModPLen, NULL, &dModQLen, NULL, &qInvLen, NULL,
					globalContext.ctx());

			if (rc != SB_SUCCESS) {
				qDebug() << "Could not do initial key get"
						<< SBError::getErrorText(rc);
			} else {
				unsigned char * e, *n, *d, *p, *q, *dModPm1, *dModQm1,
						*qInvModP;
				unsigned char ** chars[] = { &e, &n, &d, &p, &q, &dModPm1,
						&dModQm1, &qInvModP, NULL };
				allocate(sizes, chars);

				rc = hu_RSAKeyGet(rsaParams, privateKey, publicKey, &eLen, e,
						&nLen, n, &dLen, d, &pLen, p, &qLen, q, &dModPLen,
						dModPm1, &dModQLen, dModQm1, &qInvLen, qInvModP,
						globalContext.ctx());
				if (rc != SB_SUCCESS) {
					qDebug() << "Could not get values"
							<< SBError::getErrorText(rc);
				} else {
					BIGNUM * _e, *_n, *_d, *_p, *_q, *_dModPm1, *_dModQm1,
							*_qInvModP;
					BIGNUM ** bigNums[] = { &_e, &_n, &_d, &_p, &_q, &_dModPm1,
							&_dModQm1, &_qInvModP, NULL };
					toBN(sizes, chars, bigNums);

					RSA rsa;

					rsa.n = _n;
					rsa.e = _e;
					rsa.d = _d;
					rsa.p = _p;
					rsa.q = _q;
					rsa.dmp1 = _dModPm1;
					rsa.dmq1 = _dModQm1;
					rsa.iqmp = _qInvModP;

					// Encode private key
					{
						BIO * privateBio = BIO_new(BIO_s_mem());
						PEM_write_bio_RSAPrivateKey(privateBio, &rsa, NULL,
								NULL, 0, NULL, NULL);
						BUF_MEM * privateMem(NULL);
						BIO_get_mem_ptr(privateBio, &privateMem);

						dump(privateMem);

						BIO_free(privateBio);
					}

					// Encode the public key
					{
						BIO * publicBio = BIO_new(BIO_s_mem());
						PEM_write_bio_RSAPublicKey(publicBio, &rsa);

						BUF_MEM *publicMem(NULL);
						BIO_get_mem_ptr(publicBio, &publicMem);

						dump(publicMem);

						BIO_free(publicBio);
					}

					// The RSA object was not created via the library - so it isn't freed.
					// In normal OpenSSL use - correct freeing of the RSA object would also
					// free the BIGNUMs.
					destroy(bigNums);
				}

				destroy(chars);
			}
			rc = hu_RSAKeyDestroy(rsaParams, &privateKey, &publicKey,
					globalContext.ctx());
			if (rc != SB_SUCCESS) {
				qDebug() << "Warning: Could not destroy keys"
						<< SBError::getErrorText(rc);
			}
		}
		rc = hu_RSAParamsDestroy(&rsaParams, globalContext.ctx());
		if (rc != SB_SUCCESS) {
			qDebug() << "Warning: Could not destroy rsa params"
					<< SBError::getErrorText(rc);
		}

	}
}

 

--
Rob is no longer associated with BlackBerry.
Please use plain text.
Developer
smiley
Posts: 1,466
Registered: ‎07-14-2008
My Device: Z10
My Carrier: Fido

Re: How to create RAS Keys?

Thanks! That should help alot.

 

What does encoding the keys do? Is it encoding to hex and for writing to the console and for sharing public key?

 

For encryption i would just use the publicMem and privateMem handles correct?

 

 

 

Please use plain text.
BlackBerry Development Advisor (Retired)
robbieDubya
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: How to create RAS Keys?

Output:

-----BEGIN RSA PRIVATE KEY-----
MIIBPwIECAgESAJBAMTfV57ocvpjmGFnL+MVfijnL03VBYqev596PP0+6C0XPp3T
VmktKT7tuI9qOS95Kw4IG8ePnV9ZPzGNT795W/ECAwEAAQJAHgr7IwvT5/Pk4BBQ
FXZFL1bAOD9mvhWlpl+QCRFdeuvJe6Ku2kJN897R5Tm7KfRXBc/g9m5BAFokfMvq
6rrj8QIhAPBnzOEApngJoiqLl3Vwj6flJ0Y7uEQlnAukf7M7EiydAiEA0aSgpSYl
4JWmVEqiqDYBEAS8uNFo1VT/JPzTqocsKmUCIQDWSpBz2BKLWXr2FawSgR1seXVC
w6UDCctJDX7PEs6meQIhAJz24yTj7CY8Rf4Ep8bEMIV61oaWnCRmcGaUOjMK5EGV
AiEA3bY6ZySgbtqolSX2EfOBEsIBT5EGMHc+OL/SE+FEdwo=
-----END RSA PRIVATE KEY-----

-----BEGIN RSA PUBLIC KEY-----
MEgCQQDE31ee6HL6Y5hhZy/jFX4o5y9N1QWKnr+fejz9PugtFz6d01ZpLSk+7biP
ajkveSsOCBvHj51fWT8xjU+/eVvxAgMBAAE=
-----END RSA PUBLIC KEY-----

 

--
Rob is no longer associated with BlackBerry.
Please use plain text.
BlackBerry Development Advisor (Retired)
robbieDubya
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: How to create RAS Keys?

Encoding puts them into PEM / base64 representations.

 

For signing / encrypting you'd use publicKey and privateKey.

 

The 'mem' variables are just a copy of the encoded version.

 

Also worth considering - you'd need to persist and decode to use the same key between executions of the application.

--
Rob is no longer associated with BlackBerry.
Please use plain text.
Developer
smiley
Posts: 1,466
Registered: ‎07-14-2008
My Device: Z10
My Carrier: Fido

Re: How to create RAS Keys?


robbieDubya wrote:

Encoding puts them into PEM / base64 representations.

 

For signing / encrypting you'd use publicKey and privateKey.

 

The 'mem' variables are just a copy of the encoded version.

 

Also worth considering - you'd need to persist and decode to use the same key between executions of the application.


So by calling

 

PEM_write_bio_RSAPrivateKey(privateBio, &rsa, NULL,
								NULL, 0, NULL, NULL);

it will give me the actual key in the privateBio var?  I can then use this key for decryption?

Please use plain text.
BlackBerry Development Advisor (Retired)
robbieDubya
Posts: 418
Registered: ‎07-18-2012
My Device: Q10
My Carrier: Bell Canada

Re: How to create RAS Keys?

Hi,

 

I'd say "live"  and "copy of the values in the key"...

 

The privateKey and publicKey variables are live. You can use them with the huRSA functions.

 

OpenSSL's BIOs are "Basic Input Output" - they are a place to read/write data. Where I've used them here, they contain a copy of the values in the key.

 

The RSA * - contains a live copy, that could be used with OpenSSLs RSA functions (but not with huRSA unless you extract and reconstitute)

 

Most of this code is just getting all of the values from the live key - into an OpenSSL structure to encode for transmission or persistence.

--
Rob is no longer associated with BlackBerry.
Please use plain text.
Developer
smiley
Posts: 1,466
Registered: ‎07-14-2008
My Device: Z10
My Carrier: Fido

Re: How to create RAS Keys?


robbieDubya wrote:

Hi,

 

I'd say "live"  and "copy of the values in the key"...

 

The privateKey and publicKey variables are live. You can use them with the huRSA functions.

 

OpenSSL's BIOs are "Basic Input Output" - they are a place to read/write data. Where I've used them here, they contain a copy of the values in the key.

 

The RSA * - contains a live copy, that could be used with OpenSSLs RSA functions (but not with huRSA unless you extract and reconstitute)

 

Most of this code is just getting all of the values from the live key - into an OpenSSL structure to encode for transmission or persistence.


I was hoping just use RSA to generate the pub/pri keys and then use AES for encryption.  I guess that won't work.

 

I need to store the private key so can I not just save the encoded key encrypted and then create a new RSA key object and pass it the private key and then do the decryption?

 

If not what is the best method of storing the private key and use it to decrypt data? thanks

Please use plain text.