用Android实现Bouncy Castle密码算法

mco*_*ley 4 java encryption android cryptography bouncycastle

我如何使用Bouncy Castle提供程序来实现诸如Serpent和Twofish之类的算法,因为Sun的提供商根本不实现这些算法.我知道当多个提供商可以实现相同的算法时,您将获得最高等级提供商的实施,该提供商将成为Sun提供商.如果由于某种原因您想要使用特定提供程序的实现(可能因为您知道它更快),您可以在两个arg版本的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();
        }       
    }
Run Code Online (Sandbox Code Playgroud)

然而这引发了一个

java.security.NoSuchAlgorithmException:Serpent/CBC/PKCS7Padding

在我打电话的那一行

cipher = Cipher.getInstance(TRANSFORMATION,PROVIDER);

运行

$ adb shell
# logcat
Run Code Online (Sandbox Code Playgroud)

我得到了很多

not resolving ambiguous class
not verifying
multiple definitions
Run Code Online (Sandbox Code Playgroud)

输出错误.知道是什么导致这种情况发生以及我如何解决这个问题?

Rob*_*ley 6

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

Spongy Castle完全取代了随附Android的Bouncy Castle加密库的残缺版本.有一些小改动可以在Android上运行:

  • 所有包名都已从org.bouncycastle.*移到org.spongycastle.* - 所以没有类加载器冲突
  • Java Security API提供程序名称现在是SC而不是BC

"海绵城堡拯救了我的屁股." - 来自一个快乐的用户的反馈:)