java - Android RSA key 对生成-我应该使用标准Java/Bouncy CaSTLe/海绵城堡/JSch/其他吗?

标签 java android security rsa bouncycastle

我已经花了大约一个星期以上的时间来实现我想到的一种方法。我遇到(并阅读了)许多关于所有这些不同方法的文章,但我仍然感到困惑,因此我希望有人可以传播他们对这些主题的知识,以便我可以更轻松地创建我所追求的方法并在Android中实现它。

我的“寻求”方法:

  • 必须生成RSA公钥和私钥
  • 公共(public)必须具有PKCS#1填充
  • 必须为RSA 2048
  • 以字节数组
  • 返回公钥

    显然,您可以通过以下四种方法进行操作:
  • 标准Java
  • 有弹性的城堡
  • 海绵城堡(是否支持Android?)
  • JSch

  • 因为我对安全性和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(尚未开始/与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 key 生成有问题的任何人(例如我和其他许多人都拥有过的),我希望它能真正成为更多的资源。

    我觉得Bouncy CaSTLe对它的API知之甚少,这使得像我这样的初学者都很难理解它。根据我的研究,人们使用Java中的Bouncy CaSTLe而不是内置的安全提供程序,因为Bouncy CaSTLe更强大。不需要在Android中使用Bouncy CaSTLe,因为它会“附带脆弱版本的Bouncy CaSTLe一起发货”,这可能会导致错误。海绵城堡只是充气城堡的重新包装。

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

    更新

    我希望以后可以回答。至于我解决问题的方法是仅使用NDK。

    最佳答案

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

    Java的内置密码可通过Java密码扩展(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中试验了其API。第二部分是许多粘合代码,以允许该库用作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上的充气弹药已瘫痪”。

    为了在Android上实际提供bouncycaSTLe库的全功能版本,一些开发人员制作了一种叫做Spongycastle library的东西。它无非就是修改了bouncycaSTLe库,以便它可以在Android上运行。主要修改是将软件包名称从org.bouncycastle.*更改为org.spongycastle.*,以防止 namespace 冲突。

    那你应该用什么呢?这取决于您想要做什么,您的可移植性需求是什么,您的样式偏好是什么以及您的加密技术水平是什么。通常,当您使用这些库时,您将在相当低的级别上使用加密。您将重点放在如何做(使用RSA进行 key 传输,使用AES进行消息加密,使用HMAC-SHA256进行消息完整性等)与做什么(我想通过电子邮件将加密的消息发送给收件人)上。类似机制)。显然,如果可以的话,您应该使用直接解决问题的高级库。这些库已经了解PKCS#1是什么,以及如何将其用作更大更完整协议(protocol)的一部分。

    关于java - Android RSA key 对生成-我应该使用标准Java/Bouncy CaSTLe/海绵城堡/JSch/其他吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9962825/

    相关文章:

    security - Inkscape 的 --vacuum-defs 是否使 SVG 真正安全?

    java - Java 中静态和非静态内部类之间的非语法差异是什么?

    java - 对象的算术运算任务

    java - BufferedReader 在每行后面添加 ","。用空格替换逗号时遇到问题

    android - 当 `/sys/class/power_supply/battery` 不可读时 Android NDK 中的电池状态

    c - 如何使用格式字符串错误关闭 FORTIFY_SOURCE 补丁

    Java循环链表,删除不一致的地方

    android - Facebook 深度链接在 Android 中无法使用

    android - 无法将按钮标签包装在 Material Button Toggle Group 内

    java - 打开JDK最新Javax邮件未发送