当前位置: 首页 > 面试题库 >

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

易和怡
2023-03-14
问题内容

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

我的“寻求”方法:

  1. 必须生成RSA公钥和私钥
  2. 公众必须具有PKCS#1填充
  3. 必须为RSA 2048
  4. 返回字节数组中的公钥

显然,您可以通过以下四种方法进行处理:

  1. 标准Java
  2. 充气城堡
  3. 海绵城堡 (Android友好版?)
  4. 杰施

由于我对安全性和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密钥生成有问题的任何人(例如I,以及其他许多人都拥有的),我希望它能真正成为一种资源。

我觉得,充气城堡有 很少的 关于它的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将其Java环境与几个提供程序一起提供,这些提供程序一起构成了Java环境的默认提供程序集。不要太仔细地看它们,因为它们重叠并且由于历史文物而有些混乱。基本上,当使用Oracle
Java时,您要求提供诸如加密这样的加密货币KeyPairGeneratorKeyPairGenerator.getInstance("RSA");您将从这些提供程序之一中获取适当的类实例。

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

如果您更喜欢直接使用唯一的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库的东西。它无非就是修改了bouncycastle库,以便它可以在Android上运行。主要修改是为了更改包名称org.bouncycastle.*org.spongycastle.*以防止名称空间冲突。

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



 类似资料:
  • 问题内容: 目前,我正在使用此方法创建keyPair 还有另一种方法,我可以指定keySize,但不确定如何传递keySpecs? 问题答案: 您的代码已经足够,并且指定“ secp256k1”已经设置了正确的大小。该方法是一种 替代 到; 您呼叫一个或另一个,而不是两个都呼叫。如果调用指定密钥大小的密钥(例如256),则BC提供程序将尝试选择正确大小的默认曲线(对于256,它将是“ prime2

  • 我想使用生成随机密钥,但java不支持填充,在我的算法中,我必须使用相同的填充,弹性城堡确实支持,但我无法理解如何使用它生成密钥 我的代码: 我收到的错误没有这样的算法

  • 我已经创建了一个小程序来使用Bouncy Castle 1.47 API生成一个DSA/El Gamal PGP钥匙环。密钥生成过程非常顺利,没有一个错误。我使用ARRAMED输出将私钥和公钥导出到一个文件,当我尝试用GPG(确切地说是KGpg)导入生成的私钥时,我得到以下错误: 单击OK后,它告诉我只处理了1个密钥。看起来它只拿了DSA键,因为在屏幕上它显示为1024/0。 **编辑**我刚刚尝

  • 我有一个使用BouncyCastle作为安全提供者的应用程序,但是我想切换到另一个直接使用OpenSSL(consecrypt)的应用程序。我遇到的问题是,我正在使用BouncyCastle提供的密钥生成器中的ECDH“密钥”,但在我的其他库中没有类似的密钥生成器。 为了比较这两者,我将使用两种方法解码这些点,输入如下- 为提高可读性而添加换行符 使用BouncyCastle方法- 返回的是。返回

  • 目前,我正在使用此方法创建keyPair 有另一种方法,我可以在其中指定keySize,但我不确定如何传递键值?

  • 如果我在某个地方出错,请纠正我,因为我是加密领域的新手。 我使用以下命令在Java 7中生成EC密钥对: 根据:文件。神谕com/javase/7/docs/technotes/tools/windows/keytool。html#命令 keytools-genkey对-alias MyServerPair-keyalg EC-keysize 571-sigalg SHA512 with ECDS