Android的RSA密钥对生成 - 我应该使用标准的Java /充气城堡/海绵城堡/ JSch /其他? [英] Android RSA Keypair Generation - Should I use Standard Java/Bouncy Castle/Spongy Castle/JSch/Other?

查看:220
本文介绍了Android的RSA密钥对生成 - 我应该使用标准的Java /充气城堡/海绵城堡/ JSch /其他?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在四处寻找一个星期左右+实现的方法我都记在心里。我曾经碰到(和读取)许多文章对所有这些不同的方法,但我仍然感到困惑,所以我希望,也许有人可以发$ P $垫他们对这些主题的知识,所以我可以更容易地去创造我方法追捧,并在Android中实现它。

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.

我的方法追捧:

  1. 必须生成RSA公共和放大器;私钥
  2. 在公众必须PKCS#1填充
  3. 必须是RSA 2048
  4. 返回公钥Byte数组

显然,你可以去一下四种方式:

  1. 在标准的Java
  2. 充气城堡
  3. 海绵城堡的(Android的友情?)
  4. JS​​ch
  1. Standard Java
  2. Bouncy Castle
  3. Spongy Castle (Android Friendly?)
  4. JSch

由于我很新的安全性和Java作为一个整体来说,我在想,如果有人能够最后给这一切的一个很好的明确的解释。

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.

下面是我曾尝试的途径来实现我的追捧方法(如上所述)在4个不同的编程方法。如果我不知道的东西,那是因为我想不通通过相应的文档。请随时指正。

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.

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。充气城堡(尚未功能= /想法?):

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(没有带它开始/同充气城堡?):

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

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;
}

我想这真的成为更多的是资源的人,有与RSA密钥生成问题的Andr​​oid(像我,和其他许多人都有过)。

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).

我觉得充气城堡拥有的很少的有关它的信息的API,这使得它的极其困难的初学者(像我)去了解它。从我的研究中,人们用充气城堡在Java中,而不是内置的安全提供者,因为充气城堡是更强大的。使用的充气城堡在Android中不希望的,因为它附带一个残缺版充气城堡,这可能是容易出错。海绵城堡简直是充气城堡的的重新打包的。

I feel that Bouncy Castle has very little information about it's API which makes it extremely difficult for 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 desired because it "ships with a crippled version of Bouncy Castle" which may be prone to errors. Spongy Castle is simply a repackage of Bouncy Castle.

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

To this end, I will ask my final question of, which method should be used for Android?

我希望有人能回答这个问题以后。至于我就是这样做解决我的问题是只使用NDK。

I hope someone can answer this later on. As for what I did to solve my problem was to just use NDK.

推荐答案

这是复杂的,但我会尽力解释,尽我所能。我想我会开始使用Java。我讨论的是面向Java 6中,我不知道是什么在Java 7中已经改变了。

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加密扩展(JCE)。这个扩展有两个部分给它,应用程序API和服务提供商的API。该应用程序的API是与你互动的部分。您可以使用的getInstance()各种加密类的工厂方法。服务提供商方面较为混乱对于普通的程序员。他们不关心密码是如何实现的,他们只想一些作品。但引擎盖下有一些做实际工作的加密提供程序类。如果你看一下参数的getInstance()你会看到,如果你想,你可以指定供应商。为什么你曾经想?也许你已支付$$$了RSA的优化商业实现,所以要使用那一个。也许一个供应商具有FIPS认证,或者你需要为你的应用程序,一些其他的认证。然后,你将指定供应商。太阳/ Oracle的船舶的Java环境与几家供应商共同构成的默认提供的Java环境设置。别看他们太认真,因为它们是重叠的,因此混乱,由于有些历史文物。基本上,使用Oracle的Java当你问一些加密就像一个的KeyPairGenerator KeyPairGenerator.getInstance(RSA); 你会从这些供应商之一,拿到一个合适的类的实例。

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 providers that 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.

接下来,让我们看看BouncyCastle的。所述BouncyCastle的文库由两部分组成。其一是其独特的密码库的API,你已经在你的#2上面尝试了。第二部分是大量的胶水code,让这个库用作隐窝提供了JCE。这意味着你作为一个程序员有一个选择,看你如何使用BouncyCastle的加密库。您可以直接使用他们的API在2以上。或者,您可以使用JCE的API,但明确指定BouncyCastle的实施像的KeyPairGenerator KPG = KeyPairGenerator.getInstance(RSA,BC);

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");.

如果您preFER直接使用独特的BouncyCastle的API(他们称之为自己的轻量级API),那么你就没有必要让所有的胶水code用来制造它作为一个JCE提供工作。对于这个BouncyCastle的不提供下载只是轻量级的API类的。

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.

而现在,最后,我们来看看Android的实现。谷歌并没有授权Oracle的Java源代码code,所以他们没有任何Oracle的JCE提供程序。他们必须提供自己的供应商。由于BouncyCastle的有需要的所有code,并且是开源和宽松的许可,谷歌/ Android的选择使用BouncyCastle的为基础,其默认JCE提供者。不过,Android已经作出任何努力,使现有的独特轻便的API为Android程序员。他们期待您仅通过JCE使用这些类。他们已经修改了BouncyCastle的code来调整它为Android。这些事实,你可以找到,也许使用的部分的直接在Android上的轻量级API的是一个简单的事实,即它的存在,引擎盖下的副作用。而不是一切都在那里。有人形容这种情况为BouncyCastle的Andr​​oid上是残缺的。

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 some of 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上BouncyCastle的图书馆的部分开发商产生一种叫做 Spongycastle库。它无非是修改,以便它可以在Android工作BouncyCastle的库。的主要修改是改变从 org.bouncycastle包名称。* org.spongycastle。* 至prevent名字空间的冲突。

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.

所以,你应该用什么?这取决于你想做什么,你的便携性的需求是什么,你的风格preferences是,和你的密码技术水平。一般来说,当你使用这些库,你正在使用的密码在相当低的水平。你是集中在如何做到这一点(使用RSA重点运输,使用AES用于邮件加密,使用HMAC-SHA256消息完整性,等等)与该怎么做(我想通过邮件发送加密邮件给收件人样的机制)。很显然,如果你能,你应该坚持更高级别的库直接解决您的问题。这些库已经明白PKCS#1,以及如何使用它作为规模更大,更完整的协议的一部分。

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.

这篇关于Android的RSA密钥对生成 - 我应该使用标准的Java /充气城堡/海绵城堡/ JSch /其他?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆