您好我是开发ios应用程序的新手。我有一个模数和一个指数,我需要生成SecKey然后用它来加密一些数据(RSA加密)。请快速提供帮助。
答案 0 :(得分:1)
您不应该自己实施加密算法或密钥生成(在加密中不是专家)。在安全问题很重要的地方,使用成熟且知名的库和工具。
在iOS上,值得查看SecKey API(SecKeyEncrypt(_:_:_:_:_:_:)
等)。在WWDC 2016 Session 706中提到了at 16:10。
您可能会发现有用的调查CryptoCompatibility示例项目,该项目使用Apple API显示常见的加密操作。"
作为跨平台解决方案,您可以使用OpenSSL,它还提供RSA API。
答案 1 :(得分:0)
已经提出/回答了一些类似的问题,在这里您可以获取模数和指数并从中获得.PEM格式:Generate RSA Public Key from Modulus and Exponent
还有一个,尽管这个使用的是OpenSSL:https://stackoverflow.com/a/31010530/209855
另外,您可能会遇到一些建议https://github.com/StCredZero/SCZ-BasicEncodingRules-iOS的人,例如此处https://stackoverflow.com/a/10643894/209855
但是,如果您像我一样,实际上什么也没做,也没有给您您想要的东西。
如果您仔细阅读了该github存储库中的问题,就会发现iOS 8出现了问题,并且它不再生成正确的数据。
但是,有人为此发布了一个修复程序:https://github.com/Meniny/Meniny.github.io/blob/5895a2d51502881a7d6cda418beafa546874dfa7/_posts/2017-08-12-RSA_public_key_with_modulus_and_exponent.md 我会在这里重现代码,以防将来消失。
+ (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;
}
最后但并非最不重要的一点是,从Swift 3的模量和指数生成RSA公钥。
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...
}
}
答案 2 :(得分:0)
PublicKeyRSA.generatePublicKey返回以字节为单位的数据,而不返回公共密钥。我们必须使用公共密钥来加密我们的数据。