共享和存储RSA - java服务器中的公钥,反之亦然

时间:2014-05-13 10:18:00

标签: java android ios encryption rsa

我的要求是:

要求1:将公钥共享到java服务器。

步骤:

  1. 在iOS应用中生成公钥 - 私钥。
  2. 将生成的密钥存储在钥匙串中。
  3. 将生成的公钥发送到java服务器。
  4. Java服务器应该能够在数据库中存储共享公钥。
  5. 要求2:存储java服务器发送的公钥。

    步骤:

    1. Java服务器发送其他用户的公钥。
    2. 处理java服务器发送的数据并从中生成公钥。
    3. 将生成的密钥存储在钥匙串中,以后可以检索该密钥以加密要传输的邮件。
    4. 通过使用SecKeyWrapper类(CommonCrypto示例)中定义的以下方法,我能够在需求1中实现步骤1-2:

      - (void)generateKeyPair:(NSUInteger)keySize
      

      问题1:现在问题是 - 我该如何将该密钥发送到java服务器?

      我们在同一个类中有getPublicKeyBits方法,它返回一个NSData对象,在一些谷歌搜索中我发现它是DER编码格式。

      问题2:如果我将相同的NSData对象发送到服务器,我猜它会解释为ByteBuffer对象,对于其他设备,在我的情况下它可能是android,是否可以解释那些数据?

      问题3:在上述情况下分享公钥的最佳方式是什么?

      这就是我现在想要实现的目标:

      方法#1: 尝试从指数和模数生成公钥

      Android结束

      1. 在Android设备上生成公钥和私钥(使用 openssl wrapper)
      2. 从生成的公钥获得模数和指数
      3. iOS结束

        1. 从ios端使用模数和指数生成的公钥 此链接中指定的代码: https://stackoverflow.com/a/10643962/217586
        2. 使用将一些示例字符串转换为NSData的对象 NSUTF8StringEncoding
        3. 使用 - wrapSymmetricKey:keyRef:SecKeyWrapper中定义的方法 class(CryptoExercise示例)用于加密,并通过密钥获取 从步骤1和加密的数据到从步骤2获得到它
        4. 将前一步骤中获得的NSData(加密数据)转换为 base64encoded string,与android guy共享
        5. Android结束

          1. 尝试使用相关私钥
          2. 解密base64encoded字符串

            问题:

              

            获取错误 - RSA块的数据太多

            方法#2: (从此链接了解 - https://github.com/superwills/iOSRSAPublicKeyEncryption,我们不是 应该从iOS以外的任何东西加载公钥 证书,所以尝试了不同的方法)

            终端

            1. 使用此网址中指定的openssl命令生成证书: https://stackoverflow.com/a/17295321/217586
            2. iOS结束

              1. 获取上述网址
              2. 中指定的公钥
              3. 在代码下方用于加密数据:

                SecKeyWrapper * secKeyWrapper = [SecKeyWrapper sharedWrapper]; SecKeyRef获得PublicKey = [secKeyWrapper getPublicKeyRefFromDerCertificate:kCertificatePath]; NSData * dataToBeEncrypted = [kStringToBeEncrypted dataUsingEncoding:NSUTF8StringEncoding]; NSData * encryptedText = [secKeyWrapper wrapSymmetricKey:dataToBeEncrypted keyRef:acquiredPublicKey];

              4. 将NSData转换为base64encoded字符串

              5. 终端

                1. 使用以下命令将其转换回原始字符串:

                  回声| openssl rsautl -decrypt -inkey rsaPrivate.pem

                2. 问题:

                    

                  获取错误 - rsa例程:RSA_EAY_PRIVATE_DECRYPT:大于的数据   MOD   LEN:/SourceCache/OpenSSL098/OpenSSL098-47.1/src/crypto/rsa/rsa_eay.c

                  有什么建议吗?

1 个答案:

答案 0 :(得分:0)

您的第一种方法几乎与我之前在项目中使用的方法相同。区别在于我没有共享模数和指数,而是整个公钥在base 64中编码(没有----- BEGIN / END PUBLIC KEY -----页眉/页脚),来回转换为最终设备中的相应类。基本上相同的概念应用于加密数据,始终共享Base64编码数据以避免转换问题。 到目前为止,如果您没有任何转换问题,您的方法应该没问题(并且您可以通过将公钥转换为其base64表示轻松找到问题,在Android和iOS上,字符串应该完全相同,否则发生了一些不好的事情)。 您遇到的问题(getting error - too much data for RSA block)是因为您加密的文本对于您提供的密钥大小而言太大。 RSA只能加密比密钥对的模数短几个字节的消息,从而加错。您应该做的是,生成一次性加密对称密钥,用于加密/解密数据,交换使用对称密钥加密的数据和使用RSA加密的密钥。这就是任何正确设计的RSA加密方案的工作原理。

无论如何,我认为如果你尝试使用较短固定字符串的第一种方法,你应该注意到第一种方法可能正常工作(除非你实现了错误,因为你解释说理论上是正确的但是如果没看到一些代码就很难说)。

安东尼奥