【问题标题】:How to generate Publickey with use of modulus and an exponent?如何使用模数和指数生成公钥?
【发布时间】:2017-05-27 14:48:37
【问题描述】:

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

【问题讨论】:

  • 您不应该自己实现加密算法或密钥生成(不是密码学方面的专家)。如果安全很重要,请使用成熟且知名的库和工具。
  • 你能举一些例子吗?

标签: ios swift cocoapods public-key-encryption


【解决方案1】:

您不应该自己实现加密算法或密钥生成(不是密码学专家)。如果安全很重要,请使用成熟且知名的库和工具。

在 iOS 上,值得一试 SecKey API(SecKeyEncrypt(_:_:_:_:_:_:) 等)。它在 WWDC 2016 Session 706 中提到,从 at 16:10 开始。

您可能会发现调查 CryptoCompatibility 示例项目很有用,该项目“展示了使用 Apple API 的常见加密操作”。

作为一个跨平台的解决方案,您可以使用同样提供RSA API 的 OpenSSL。

【讨论】:

  • 问题似乎不是如何生成密钥,而是如何获取生成的模数和指数数据并将其转换为可用格式。
  • @AaronAsh 事实上,这个答案暗示了一个更好的方向来寻找作者问题的解决方案,从最初的问题来看,在我看来是XY kind。如果它对您没有帮助,提出一个新问题可能是一个不错的选择。
【解决方案2】:

已经提出/回答了一些类似的问题,在这里您可以获取模数和指数并从中获取 .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...
  }
}

【讨论】:

  • PublicKeyRSA.generatePublicKey 给出了这个错误:“使用未解析的标识符 'PublicKeyRSA'”
  • generateRSAPublicKeyWithModulus 键放入一些您可以从swift 调用的Objective-C 文件中,然后调用它。我只是在 Objective-C 中使用它。您可能需要设置一个桥接头。
【解决方案3】:

PublicKeyRSA.generatePublicKey 以字节为单位返回数据,而不是返回公钥。我们必须使用公钥来加密我们的数据。

【讨论】:

  • 您可能想在 Stack Overflow 上提问并在您的问题中添加指向此问题的链接。关于那个问题,请具体解释为什么这个问题不能解决您的问题。
猜你喜欢
  • 2015-06-22
  • 2017-03-29
  • 1970-01-01
  • 2021-05-01
  • 2013-04-07
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
相关资源
最近更新 更多