【问题标题】:Implementing Bouncy Castle Cipher Algorithms with Android使用 Android 实现 Bouncy Castle 密码算法
【发布时间】:2011-05-17 22:25:59
【问题描述】:

我如何使用 Bouncy Castle 提供程序来实现 Serpent 和 Twofish 等算法,因为 Sun 的提供程序根本不实现这些。我知道当多个提供商可以实现相同的算法时,您会从排名最高的提供商那里获得实现,这将是 Sun 提供商。如果出于某种原因您想使用来自特定提供程序的实现(可能是因为您知道它更快),您可以在 getInstance() 的双参数版本中指定提供程序。就我而言,Sun 提供商根本没有实现我感兴趣的算法。

我已经尝试实现 Serpent:

    public static final String FILE_EXTENSION = ".serpent";
    public static final String PROVIDER = "BC"; // Bouncy Castle
    public static final String BLOCK_CIPHER = "Serpent";
    public static final String TRANSFORMATION = "Serpent/CBC/PKCS7Padding";
    public static final String KEY_ALGORITHM = "PBKDF2WithHmacSHA1";
    public static final String PRNG_ALGORITHM = "SHA1PRNG";

    public static final int BLOCK_SIZE = 128; // bits
    public static final int KEY_SIZE = 256; // bits
    public static final int ITERATION_COUNT = 1024; // for PBE

    /** Performs the encryption of a file. */
    public void encrypt(String pathname, char[] password, byte[] salt) {
        // Use bouncy castle as our provider
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        // Convert the file into a byte array
        byte[] plaintext = fileToBytes(new File(pathname));

        // Generate a 256-bit key
        SecretKey key = generateSecretKey(password,salt);

        // Generate a 128-bit secure random IV
        byte[] iv = generateIV();

        // Setup the cipher and perform the encryption
        Cipher cipher = null;
        byte[] ciphertext = null;
        try {
            cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
            ciphertext = cipher.doFinal(plaintext);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Append the IV to the ciphertext
        byte[] temp = new byte[iv.length+ciphertext.length];
        System.arraycopy(iv, 0, temp, 0, iv.length);
        System.arraycopy(ciphertext, 0, temp, iv.length, ciphertext.length);
        ciphertext = temp;

        // Store the encrypted file in the same directory we found it
        if (Environment.getExternalStorageDirectory().canWrite()) {
            bytesToFile(ciphertext, pathname+FILE_EXTENSION);
            File file = new File(pathname);
            file.delete();
        }       
    }

然而这会抛出一个

java.security.NoSuchAlgorithmException: Serpent/CBC/PKCS7Padding

在我打电话的那一行

密码= Cipher.getInstance(转换, 提供者);

跑步

$ adb shell
# logcat

我得到了很多

not resolving ambiguous class
not verifying
multiple definitions

正在输出错误。知道什么会导致这种情况发生以及如何解决这个问题吗?

【问题讨论】:

  • 为我工作。您使用的是古代版本的 bouncycastle 吗?
  • 我实际上是将此代码作为 Android 应用程序的一部分包含在内,这会有所不同吗?我正在使用赏金城堡 1.46
  • 对不起,我对安卓一窍不通。
  • 谢谢,是的,我正在运行 Android adb shell->logcat,我收到大量未“解决模棱两可的类”和“未验证”错误,所以我认为这是一个 Android 问题。我将编辑我的原始帖子。

标签: java android encryption cryptography bouncycastle


【解决方案1】:

您可能想要Spongy Castle - 我用 Bouncy Castle 制作的专门针对 Android 的重新包装。

Spongy Castle 完全替代了 Android 随附的 Bouncy Castle 加密库的残缺版本。有几个小改动可以让它在 Android 上运行:

  • 所有包名已从 org.bouncycastle.* 移至 org.spongycastle.* - 因此没有类加载器冲突
  • Java 安全 API 提供程序名称现在是 SC 而不是 BC

“海绵城堡救了我的命。” - 来自一位快乐用户的反馈 :)

【讨论】:

  • 我是 Spongy Castle 的新手,您能提供有关如何在我的应用上使用 Spongy Castle 的任何教程吗?
【解决方案2】:

javap org.bouncycastle.jce.provider.symmetric.Serpent 产生什么?如果找不到类,则表明充气城堡包中缺少某些内容,或者您​​可能使用了不正确的类。

如果您使用的是 1.4 VM,则需要将 jar 文件安装在 $JAVA_HOME/jre/lib/ext 中,否则 IIRC 将无法正常工作。

检查 zipinfo bcprov-jdk16-146.jar 的输出 | grep '/symmetric/' 用于 Serpent 类。同样,这是为了交叉检查软件包的正确安装以及 Serpent 对称算法的存在。

我做了一个简单的测试,使用的代码与你自己的非常相似,它没有产生异常。

好的,提供程序存在于系统中,但发生的是内部充气城堡实现在您链接的那个之前加载。内部实现不包含 Serpent/CBC/PKCS7Padding 代码,并且即使您添加了 bouncycastle 提供程序,它也不会替换已注册的提供程序。

内部提供者只实现了少数密码,即。 AES、ARC4、Blowfish 和 DESede

我使用以下存根活动来确定这一点:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    Cipher cipher = null;
    TextView tv = new TextView(this);
    setContentView(tv);

    for (String name : SYMMETRIC_CIPHERS) {
    try {
        cipher = Cipher.getInstance(name, "BC");
        tv.append(name);
        tv.append("\n");
    } catch (Exception e) {
    }
    }
}

来自 BouncyCastleProvider 源代码的提供者列表:

private static final String[] SYMMETRIC_CIPHERS =
{
    "AES", "ARC4", "Blowfish", "Camellia", "CAST5", "CAST6", "DESede", "Grainv1", "Grain128", "HC128", "HC256", "IDEA",
    "Noekeon", "RC5", "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Skipjack", "TEA", "Twofish", "VMPC", "VMPCKSA3", "XTEA"
};

我知道它对你没有帮助,但你为什么不使用 AES?

【讨论】:

  • zipinfo 的输出显示 Serpent$AlgParams.class、Serpent$ECB.class、Serpent$KeyGen.class、Serpent$Mappings.class 和 Serpent.class 都存在。在 Android 上运行它会是原因吗?
  • 我更新了答案 - 看起来 android bouncycastle 提供程序只有少数来自实现的完整密码列表(这并不奇怪)。您无法重新注册提供程序,因为运行时中的类引用在添加 jar 文件之前解析为内部类。
猜你喜欢
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 2022-09-29
  • 2011-01-26
  • 2015-06-13
  • 1970-01-01
相关资源
最近更新 更多