我一直在寻找一周左右的时间来实现我想到的方法。我已经看过很多关于所有这些不同方法的文章,但我仍然感到困惑,所以我希望有人可以传播他们对这些主题的知识,这样我就可以更轻松地创建我追捧的方法和在Android中实现它。
我的“追捧”方法:
显然你可以通过四种方式解决这个问题:
由于我对安全性和Java整体都很陌生,所以我想知道是否有人能够最终对所有这些做出明确的解释。
以下是我尝试在4种不同编程方法中实现我追捧的方法(如上所述)的方法。如果我不知道它是什么,因为我无法弄清楚各自的文件。请随时纠正我。
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;
}
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
}
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。
答案 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时,您需要一些加密,如KeyPairGenerator
到KeyPairGenerator.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