Hi I am new for developing the ios application. I have a modulus and an exponent and i need to generate SecKey and then use this to encrypt some data (RSA encryption). Please any one help in swift.
-
3You should not implement crypto algorithms or key generation by yourself (not being _an expert_ in cryptography). Where security matters, use mature and well-known libraries and tools. – werediver Jan 12 '17 at 13:23
-
can you gave some sample example? – vara Jan 13 '17 at 07:11
3 Answers
You should not implement crypto algorithms or key generation by yourself (not being an expert in cryptography). Where security matters, use mature and well-known libraries and tools.
On iOS it's worth checking out SecKey API (SecKeyEncrypt(_:_:_:_:_:_:)
and so on). It was mentioned at WWDC 2016 Session 706 starting at 16:10.
You may find useful investigating the CryptoCompatibility example project which "shows common cryptographic operations using Apple APIs."
As a cross-platform solution you can use OpenSSL which also provides RSA API.

- 4,667
- 1
- 29
- 49
-
It seems the question was not about how to generate keys, but how to take the generated modulus and exponent data and convert it into a useable format. – Aaron Ash Jun 22 '18 at 14:43
-
@AaronAsh In fact, this answer suggests a potentially better direction to look to for a solution of the the author's problem, which from the original question appears to me to be of an [XY kind](https://en.wikipedia.org/wiki/XY_problem). If it doesn't help you, asking a new question might be a good option. – werediver Jun 22 '18 at 15:03
A few similar questions have been asked/answered already, here's one where you can take a modulus and exponent and get a .PEM format out of it: Generate RSA Public Key from Modulus and Exponent
Here's another, although this one uses OpenSSL: https://stackoverflow.com/a/31010530/209855
Additionally, you've probably run into some people recommending https://github.com/StCredZero/SCZ-BasicEncodingRules-iOS like here https://stackoverflow.com/a/10643894/209855
But if you're like me, nothing actually worked or gave you exactly what you wanted.
If you read through the issues on that github repo, you'll find something broke around iOS 8 and it no longer generates the correct data.
However, someone posted a fix for this: https://github.com/Meniny/Meniny.github.io/blob/5895a2d51502881a7d6cda418beafa546874dfa7/_posts/2017-08-12-RSA_public_key_with_modulus_and_exponent.md I'll reproduce the code here, in case it disappears in the future.
+ (NSData * __nullable)generateRSAPublicKeyWithModulus:(NSData * __nonnull)modulus exponent:(NSData * __nonnull)exponent {
const uint8_t DEFAULT_EXPONENT[] = {0x01, 0x00, 0x01,}; //default: 65537
const uint8_t UNSIGNED_FLAG_FOR_BYTE = 0x81;
const uint8_t UNSIGNED_FLAG_FOR_BYTE2 = 0x82;
const uint8_t UNSIGNED_FLAG_FOR_BIGNUM = 0x00;
const uint8_t SEQUENCE_TAG = 0x30;
const uint8_t INTEGER_TAG = 0x02;
uint8_t* modulusBytes = (uint8_t*)[modulus bytes];
uint8_t* exponentBytes = (uint8_t*)(exponent == nil ? DEFAULT_EXPONENT : [exponent bytes]);
//(1) calculate lengths
//- length of modulus
int lenMod = (int)[modulus length];
if (modulusBytes[0] >= 0x80)
lenMod ++; //place for UNSIGNED_FLAG_FOR_BIGNUM
int lenModHeader = 2 + (lenMod >= 0x80 ? 1 : 0) + (lenMod >= 0x0100 ? 1 : 0);
//- length of exponent
int lenExp = exponent == nil ? sizeof(DEFAULT_EXPONENT) : (int)[exponent length];
int lenExpHeader = 2;
//- length of body
int lenBody = lenModHeader + lenMod + lenExpHeader + lenExp;
//- length of total
int lenTotal = 2 + (lenBody >= 0x80 ? 1 : 0) + (lenBody >= 0x0100 ? 1 : 0) + lenBody;
int index = 0;
uint8_t* byteBuffer = malloc(sizeof(uint8_t) * lenTotal);
memset(byteBuffer, 0x00, sizeof(uint8_t) * lenTotal);
//(2) fill up byte buffer
//- sequence tag
byteBuffer[index ++] = SEQUENCE_TAG;
//- total length
if(lenBody >= 0x80)
byteBuffer[index ++] = (lenBody >= 0x0100 ? UNSIGNED_FLAG_FOR_BYTE2 : UNSIGNED_FLAG_FOR_BYTE);
if(lenBody >= 0x0100) {
byteBuffer[index ++] = (uint8_t)(lenBody / 0x0100);
byteBuffer[index ++] = lenBody % 0x0100;
}
else
byteBuffer[index ++] = lenBody;
//- integer tag
byteBuffer[index ++] = INTEGER_TAG;
//- modulus length
if (lenMod >= 0x80)
byteBuffer[index ++] = (lenMod >= 0x0100 ? UNSIGNED_FLAG_FOR_BYTE2 : UNSIGNED_FLAG_FOR_BYTE);
if (lenMod >= 0x0100) {
byteBuffer[index ++] = (int)(lenMod / 0x0100);
byteBuffer[index ++] = lenMod % 0x0100;
}
else
byteBuffer[index ++] = lenMod;
//- modulus value
if (modulusBytes[0] >= 0x80)
byteBuffer[index ++] = UNSIGNED_FLAG_FOR_BIGNUM;
memcpy(byteBuffer + index, modulusBytes, sizeof(uint8_t) * [modulus length]);
index += [modulus length];
//- exponent length
byteBuffer[index ++] = INTEGER_TAG;
byteBuffer[index ++] = lenExp;
//- exponent value
memcpy(byteBuffer + index, exponentBytes, sizeof(uint8_t) * lenExp);
index += lenExp;
if (index != lenTotal)
NSLog(@"lengths mismatch: index = %d, lenTotal = %d", index, lenTotal);
NSMutableData* buffer = [NSMutableData dataWithBytes:byteBuffer length:lenTotal];
free(byteBuffer);
return buffer;
}
And last but not least, to generate the RSA Public Key from a Modulus and Exponent in Swift 3:
public func encrypt(_ string: String, modulus: String, exponent: String) -> String? {
if let modData = Data(base64Encoded: modulus),
let expData = Data(base64Encoded: exponent),
let keyData = PublicKeyRSA.generatePublicKey(withModulus: modData, exponent: expData) {
/// encrypt...
}
}

- 1,412
- 13
- 24
-
PublicKeyRSA.generatePublicKey gave this error: "Use of unresolved identifier 'PublicKeyRSA'" – utarid Jul 28 '18 at 13:46
-
Put the `generateRSAPublicKeyWithModulus` key in some Objective-C file you can call from swift, and call it. I just used it from Objective-C. You probably need to setup a bridging header. – Aaron Ash Aug 01 '18 at 13:05
PublicKeyRSA.generatePublicKey is returning the data in bytes, not returning the public key. We have to use the public keys to encrypt our data.
-
You might want to ask a question on Stack Overflow and add a link to this question in your question. On that question, explain specifically why this question does not solve your problem. – TonyStark4ever Apr 13 '20 at 20:56