如何使用模数和指数生成Publickey?

时间:2017-01-12 13:12:11

标签: ios swift cocoapods public-key-encryption

您好我是开发ios应用程序的新手。我有一个模数和一个指数,我需要生成SecKey然后用它来加密一些数据(RSA加密)。请快速提供帮助。

3 个答案:

答案 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返回以字节为单位的数据,而不返回公共密钥。我们必须使用公共密钥来加密我们的数据。