Android RSA Keypair Generation - 我应该使用Standard Java / Bouncy Castle / Spongy Castle / JSch / Other吗?

时间:2012-04-01 07:57:25

标签: java android security rsa bouncycastle

我一直在寻找一周左右的时间来实现我想到的方法。我已经看过很多关于所有这些不同方法的文章,但我仍然感到困惑,所以我希望有人可以传播他们对这些主题的知识,这样我就可以更轻松地创建我追捧的方法和在Android中实现它。

我的“追捧”方法:

  1. 必须生成RSA Public&私钥
  2. 公众必须拥有PKCS#1 padding
  3. 必须是RSA 2048
  4. 以字节数组返回公钥
  5. 显然你可以通过四种方式解决这个问题:

    1. 标准Java
    2. Bouncy Castle
    3. Spongy Castle (Android友好?)
    4. JS​​ch
    5. 由于我对安全性和Java整体都很陌生,所以我想知道是否有人能够最终对所有这些做出明确的解释。

      以下是我尝试在4种不同编程方法中实现我追捧的方法(如上所述)的方法。如果我不知道它是什么,因为我无法弄清楚各自的文件。请随时纠正我。

      1。标准Java(不确定PKCS#1):

      public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
          KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
          kpg.initialize(2048);
          KeyPair keyPair = kpg.genKeyPair();
          byte[] pri = keyPair.getPrivate().getEncoded();
          byte[] pub = keyPair.getPublic().getEncoded();
          return pub;
      }
      

      2。 Bouncy Castle(尚未功能= /创意?):

      public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
          RSAKeyPairGenerator r = new RSAKeyPairGenerator();
          r.init(new KeyGenerationParameters(new SecureRandom(),4096));
          AsymmetricCipherKeyPair keys = r.generateKeyPair();
          CipherParameters pri = keys.getPrivate();
          CipherParameters pub = keys.getPublic();
          byte[] pubbyte = pub.toString().getBytes();
          return pubbyte; //NOT WORKING
      }
      

      3。 SpongyCastle(Hav没有开始/与Bouncy Castle相同?):

      4。 JSch(非常功能/正在进行的工作)

      public byte[] returnPublicKeyInBytes(JSch jSch) {
          try { 
              KeyPair keyPair = KeyPair.genKeyPair(jSch, KeyPair.RSA);
              ByteArrayOutputStream bs = new ByteArrayOutputStream(); 
              keyPair.writePrivateKey(bs); 
              jSch.addIdentity("Generated", bs.toByteArray(), keyPair.getPublicKeyBlob(), null);
              return keyPair.getPublicKeyBlob(); 
          } catch (JSchException e) { 
              // TODO Auto-generated catch block 
              e.printStackTrace(); 
          }
          return null;
      }
      

      对于那些在Android中遇到RSA密钥生成问题的人来说,我真的希望这能成为更多的资源(就像我和许多其他人一样)。


      我觉得Bouncy Castle有关于它的API的很少的信息,这使得非常难以让初学者(像我一样)理解它。根据我的研究,人们使用Java中的Bouncy Castle而不是内置的安全提供程序,因为 Bouncy Castle更加强大。在Android中使用 Bouncy Castle是不可取的因为它“带有残缺版本的Bouncy Castle”,这可能容易出错。 Spongy Castle只是Bouncy Castle的重新包装

      为此,我将问我最后一个问题,哪种方法应该用于Android?

      更新

      我希望有人可以稍后回答这个问题。至于我做了什么来解决我的问题就是使用NDK。

2 个答案:

答案 0 :(得分:45)

这很复杂,但我会尽力解释。我想我会从Java开始。我的讨论面向Java 6,我不确定Java 7中发生了什么变化。

Java'内置加密可通过Java Cryptography Extension(JCE)获得。此扩展包含两个部分,即应用程序API和服务提供程序API。应用程序API是您与之交互的部分。您使用各种加密类的getInstance()工厂方法。对于普通程序员来说,服务提供商方面更令人困惑。他们不关心密码是如何实现的,他们只是想要一些有效的东西。但在引擎盖下有加密提供程序类来完成实际工作。如果你查看getInstance()的参数,你会发现你可以根据需要指定提供者。你为什么想要?也许你已经为优化的RSA商业实现付了$$$,所以你想要使用那个。也许一个提供商拥有您的应用所需的FIPS证书或其他一些证书。然后,您将指定该提供程序。 Sun / Oracle ships their Java environment with several providers共同构成其Java环境的默认提供程序集。不要太仔细地看它们,因为它们是重叠的,因此会因历史文物而有些混乱。基本上,在使用Oracle Java时,您需要一些加密,如KeyPairGeneratorKeyPairGenerator.getInstance("RSA");,您将从其中一个提供程序中获取适当的类实例。

接下来,让我们看一下bouncycastle。 bouncycastle图书馆由两部分组成。一个是他们独特的加密库,您已经在上面的#2中进行了实验。第二部分是很多粘合代码,允许这个库用作JCE的crypt提供者。这意味着您作为程序员可以选择如何使用bouncycastle加密库。您可以像上面的#2一样直接使用他们的API。或者,您可以使用JCE api,但通过类似KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");的内容明确指定bouncycastle实现。

如果您更喜欢直接使用独特的bouncycastle API(他们称之为“轻量级API”),那么您就不需要使用所有粘合代码来使其作为JCE提供程序工作。对于这个bouncycastle确实提供了轻量级API类的下载。

现在,最后,我们来看看Android的实现。 Google未授权Oracle的Java源代码,因此他们没有任何Oracle的JCE提供商。他们必须提供自己的提供者。由于bouncycastle拥有所需的所有代码,并且是开源和自由许可的,因此Google / Android选择使用bouncycastle作为其默认JCE提供商的基础。但是,Android并没有努力为Android程序员提供独特的轻量级API。他们希望您仅通过JCE使用这些课程。他们修改了bouncycastle代码以针对Android调整它。事实上,你可以直接在Android上找到并且可能直接使用轻量级API的某些,这只不过是它在幕后的事实的副作用。并非一切都在那里。有些人将这种情况描述为“Android上的bouncycastle已经瘫痪”。

为了在Android上实际提供bouncycastle库的全功能版本,一些开发人员制作了一个名为Spongycastle library的东西。它只不过是修改过的bouncycastle库,因此它可以在Android上运行。主要修改是将包名称从org.bouncycastle.*更改为org.spongycastle.*以防止命名空间冲突。

那么你应该用什么?这取决于你想要做什么,你的便携性需求是什么,你的风格偏好是什么,以及你的技能水平是什么。通常,当您使用这些库时,您使用的是相当低级别的加密。您正专注于如何操作(使用RSA进行密钥传输,使用AES进行邮件加密,使用HMAC-SHA256进行邮件完整性等)与做什么(我想通过电子邮件将加密邮件发送给收件人)类似的机制)。显然,如果可以的话,你应该坚持直接解决问题的高级库。这些库已经了解PKCS#1是什么以及如何将其用作更大和更完整的协议的一部分。

答案 1 :(得分:1)

我今天早些时候正在帮助一个有弹性城堡的人。他的代码确实有效,所以请查看

RSA key pairs generating using bouncy castle. Making code runnable from java program