Android RSA 密钥对生成 - 我应该使用标准 Java/Bouncy Castle/Spongy Castle/JSch/Other 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9962825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android RSA Keypair Generation - Should I use Standard Java/Bouncy Castle/Spongy Castle/JSch/Other?
提问by EGHDK
I've been looking around for about a week+ to implement a method I have in mind. I have came across (and read) many articles on all of these different methods, but I am still left confused, so I was hoping maybe someone can spread their knowledge of these topics so I can more easily go about creating my sought after method and implementing it in Android.
我一直在寻找大约一周以上的时间来实现我想到的方法。我遇到(并阅读)了许多关于所有这些不同方法的文章,但我仍然感到困惑,所以我希望有人可以传播他们对这些主题的知识,这样我就可以更轻松地创建我追捧的方法和在 Android 中实现它。
My "sought after" method:
我的“追捧”方法:
- Must generate RSA Public & Private keys
- Public must have PKCS#1 padding
- Must be RSA 2048
- Return Public Key in Byte array
- 必须生成 RSA 公钥和私钥
- 公共必须有 PKCS#1 填充
- 必须是 RSA 2048
- 返回字节数组中的公钥
Apparently you can go about it four ways:
显然,您可以通过四种方式进行操作:
- Standard Java
- Bouncy Castle
- Spongy Castle (Android Friendly?)
- JSch
- 标准Java
- 充气城堡
- 海绵城堡(Android 友好?)
- 学士
Since I'm very new to security and Java as a whole I was wondering if someone could finally give a good clear cut explanation of all of this.
由于我对安全性和 Java 整体还是很陌生,我想知道是否有人最终可以对所有这些做出明确的解释。
Below are the ways I have tried to implement my sought after method (mentioned above) in the 4 different programming methods. If I don't know something it's because I can't figure out through the respective documentation. Please feel free to correct me.
以下是我尝试在 4 种不同的编程方法中实现我追捧的方法(如上所述)的方法。如果我不知道某些事情,那是因为我无法通过相应的文档弄清楚。请随时纠正我。
1. Standard Java (Not sure if PKCS#1):
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 (Not yet functional =/ Ideas?):
2. 充气城堡(尚未运行 =/ 创意?):
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 (Havn't started it/Same as Bouncy Castle?):
3. SpongyCastle(还没开始/和Bouncy Castle一样?):
4. JSch (Very Dis-functional/Work in progress)
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;
}
I'd like this to really become more of a resource for anyone that has problems with RSA key generation in Android (like I, and many others have had).
对于在 Android 中生成 RSA 密钥有问题的任何人(就像我和许多其他人一样),我希望它真正成为更多资源。
I feel that Bouncy Castle has very littleinformation about it's API which makes it extremely difficultfor a beginner (like me) to understand it. From my research, people use Bouncy Castle in Java instead of the built-in security provider because Bouncy Castle is much more robust. Using Bouncy Castle in Android is not desiredbecause it "ships with a crippled version of Bouncy Castle" which may be prone to errors. Spongy Castle is simply a repackageof Bouncy Castle.
我觉得,充气城堡有很少的关于它的API的信息,这使得它非常困难的初学者(像我)去了解它。根据我的研究,人们使用 Java 中的 Bouncy Castle 而不是内置的安全提供程序,因为Bouncy Castle 更加健壮。在 Android 中使用Bouncy Castle 是不可取的,因为它“附带有缺陷的 Bouncy Castle 版本”,这可能容易出错。海绵城堡只是充气城堡的重新包装。
To this end, I will ask my final question of, which method should be used for Android?
为此,我将问我的最后一个问题,Android 应该使用哪种方法?
Update
更新
I hope someone can answer this later on. As for what I did to solve my problem was to just use NDK.
我希望以后有人能回答这个问题。至于我为解决我的问题所做的只是使用 NDK。
回答by President James K. Polk
It is complicated, but I'll try to explain as best I can. I think I'll start with Java. My discussion is geared to Java 6, I'm not sure what has changed in Java 7.
这很复杂,但我会尽力解释。我想我将从Java开始。我的讨论是针对 Java 6 的,我不确定 Java 7 中发生了什么变化。
Java' built-in cryptography is available through the Java Cryptography Extension (JCE). This extension has two parts to it, the application API and service provider API. The application API is the part you interact with. You use the getInstance()
factory methods of various crypto classes. The service provider aspect is more confusing for the average programmer. They don't care about how the crypto is implemented, they just want something that works. But under the hood there are the crypto provider classes that do the actual work. If you look at the arguments to getInstance()
you'll see that you can specify the provider if you want. Why would you ever want to? Maybe you have paid $$$ for an optimized commercial implementation of RSA, so you want to use that one. Perhaps one provider has a FIPS certificate or some other certification that you need for your app. Then you would specify that provider. Sun/Oracle ships their Java environment with several providersthat together comprise the default provider set for their Java environment. Don't look at them too carefully because they are overlapping and thus confusing due somewhat to historical artifacts. Basically, when using Oracle Java you ask for some crypto like a KeyPairGenerator
through KeyPairGenerator.getInstance("RSA");
you're going to get an appropriate class instance from one of these providers.
Java 的内置加密可通过 Java 加密扩展 (JCE) 获得。这个扩展有两个部分,应用程序 API 和服务提供者 API。应用程序 API 是您与之交互的部分。您使用getInstance()
各种加密类的工厂方法。对于普通程序员来说,服务提供者方面更令人困惑。他们不关心加密是如何实现的,他们只想要一些有效的东西。但在幕后,有执行实际工作的加密提供程序类。如果你看一下论据getInstance()
你会看到你可以根据需要指定提供者。为什么你会想要?也许您已经为 RSA 的优化商业实现支付了 $$$,因此您想使用该实现。也许某个提供商拥有您的应用程序所需的 FIPS 证书或其他一些认证。然后您将指定该提供者。Sun/Oracle为其 Java 环境提供了多个提供程序,这些提供程序共同构成了为其 Java 环境设置的默认提供程序。不要太仔细地看它们,因为它们是重叠的,因此由于历史文物而令人困惑。基本上,在使用 Oracle Java 时,您会要求一些加密,例如KeyPairGenerator
通过,KeyPairGenerator.getInstance("RSA");
您将从这些提供者之一获得适当的类实例。
Next, lets look at bouncycastle. The bouncycastle library consists of two parts. One is their unique crypto library whose API you have experimented with in your #2 above. The second part is a lot of glue code to allow this library to be used as crypt provider for the JCE. This means you as a programmer have a choice as to how you use the bouncycastle crypto library. You can use their API directly as in #2 above. Or, you can use the JCE api but explicitly specify the bouncycastle implementation by something like KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
.
接下来,让我们看看 bouncycastle。bouncycastle 库由两部分组成。一个是他们独特的加密库,您已经在上面的 #2 中尝试了其 API。第二部分是大量的胶水代码,以允许将此库用作 JCE 的 crypt 提供程序。这意味着您作为程序员可以选择如何使用 bouncycastle 加密库。你可以直接使用他们的 API,就像上面的 #2 一样。或者,您可以使用 JCE api,但通过类似KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
.
If you prefer to use the unique bouncycastle API directly (they call it their "lightweight API") then you have no need for all the glue code used to make it work as a JCE provider. For this bouncycastle does provide a download of just the lightweight API classes.
如果您更喜欢直接使用独特的 bouncycastle API(他们称其为“轻量级 API”),那么您不需要所有用于使其作为 JCE 提供程序工作的胶水代码。对于这个 bouncycastle 确实提供了轻量级 API 类的下载。
And now, at last, we look at Android's implementation. Google didn't license Oracle's Java source code, so they didn't have any of Oracle's JCE providers. They had to provide their own providers. Since bouncycastle had all the code needed, and was open source and liberally licensed, Google/Android chose to use bouncycastle as the basis for their default JCE provider. But, Android has made no effort to make available the unique lightweight API for Android programmers. They expect you to use these classes solely through the JCE. They have modified the bouncycastle code to tune it for Android. They fact that you can find and maybe use someof the lightweight API directly on Android is simply a side-effect of the fact that it's there under the hood. And not everything is there. Some have described this situation as "bouncycastle on Android is crippled".
现在,最后,我们看看 Android 的实现。Google 没有许可 Oracle 的 Java 源代码,因此他们没有任何 Oracle 的 JCE 提供程序。他们必须提供自己的供应商。由于 bouncycastle 拥有所需的所有代码,并且是开源的并获得了自由许可,因此 Google/Android 选择使用 bouncycastle 作为其默认 JCE 提供程序的基础。但是,Android 并没有努力为 Android 程序员提供独特的轻量级 API。他们希望您仅通过 JCE 使用这些类。他们修改了 bouncycastle 代码以针对 Android 对其进行调整。事实上,你可以找到并可能使用一些直接在 Android 上使用轻量级 API 只是它存在于幕后这一事实的副作用。并不是所有的东西都在那里。有人将这种情况描述为“Android 上的 bouncycastle 已瘫痪”。
To actually provide a full featured version of the bouncycastle library on Android some developers produced something called the Spongycastle library. It is nothing more than the bouncycastle library modified so that it can work on Android. The chief modification was to change the package names from org.bouncycastle.*
to org.spongycastle.*
to prevent namespace conflicts.
为了在 Android 上真正提供一个完整的bouncycastle 库版本,一些开发者制作了一个叫做Spongycastle 库的东西。它只不过是修改了 bouncycastle 库,以便它可以在 Android 上运行。主要的修改是将包名从 更改org.bouncycastle.*
为org.spongycastle.*
以防止命名空间冲突。
So what should you use? That depends on what you want to do, what your portability needs are, what your style preferences are, and what you crypto skill level is. In general, when you are using these libraries you are using crypto at fairly low level. You are concentrating at how to do it (use RSA for key transport, use AES for message encryption, use HMAC-SHA256 for message integrity, etc.) versus what to do (I want to send an encrypted message to a recipient via an email-like mechanism). Obviously, if you can you should stick to higher-level libraries that directly solve your problem. These libraries already understand what PKCS#1 is and how to use it as part of larger and more complete protocols.
那么你应该使用什么?这取决于您想要做什么、您的便携性需求是什么、您的风格偏好是什么以及您的加密技术水平是什么。通常,当您使用这些库时,您使用的加密级别相当低。您专注于如何做(使用 RSA 进行密钥传输,使用 AES 进行消息加密,使用 HMAC-SHA256 进行消息完整性等)而不是做什么(我想通过电子邮件向收件人发送加密消息-类似机制)。显然,如果可以,您应该坚持使用直接解决您的问题的更高级别的库。这些库已经了解 PKCS#1 是什么以及如何将其用作更大更完整协议的一部分。
回答by Mayank
I was helping somebody earlier today with bouncy castle today. His code does work, so check it out
今天早些时候,我正在用充气城堡帮助某人。他的代码确实有效,所以检查一下
RSA key pairs generating using bouncy castle. Making code runnable from java program