在黑莓手机中使用NoPadding进行AES加密

时间:2013-09-17 07:27:38

标签: java encryption blackberry aes

我是黑莓开发新手,完成了使用AES / ECB / NoPadding进行加密和解密的任务。我使用下面的代码来自互联网。

加密方法:

public static byte[] encrypt( byte[] keyData,String message )
    throws Exception
{


        byte[] data = message.getBytes("UTF-8");

        // Create the AES key to use for encrypting the data.
        // This will create an AES key using as much of the keyData
        // as possible.


        if ((data.length % 16) != 0 ) {
            StringBuffer buffer = new StringBuffer(message);
            int moduleOut = data.length % 16;
            int padding =  16 - moduleOut;
            for(int i = 0 ; i < padding; i++){
                buffer.append(" ");
            }
            data = buffer.toString().getBytes("UTF-8");
        }

        AESKey key = new AESKey( keyData);

        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream(data.length);
        AESEncryptorEngine engine = new AESEncryptorEngine(key);
        BlockEncryptor encryptor = new BlockEncryptor(engine, out);


        encryptor.write(data,0,data.length);
        int finalLength = out.size();
        byte[] cbytes = new byte[finalLength];
        System.arraycopy(out.toByteArray(), 0, cbytes, 0, finalLength);
//      encryptor.close();
//      out.close();
        return cbytes;

    }

解密方法:

    public static byte[] decrypt(byte[] keyData, byte[] base64EncodedData)
    throws CryptoException, IOException 
    {

//      String base64EncodedData=new String(base64EncodedData);

        byte[] cipherText =Base64ToBytes(new String(base64EncodedData));
        // First, create the AESKey again.
        AESKey key = new AESKey(keyData);

        // Now, create the decryptor engine.
        AESDecryptorEngine engine = new AESDecryptorEngine(key);

        // Create the BlockDecryptor to hide the decryption details away.
        ByteArrayInputStream input = new ByteArrayInputStream(cipherText);
        BlockDecryptor decryptor = new BlockDecryptor(engine, input);

        // Now, read in the data.
        byte[] temp = new byte[100];
        DataBuffer buffer = new DataBuffer();

        for (;;) 
        {
            int bytesRead = decryptor.read(temp);
            buffer.write(temp, 0, bytesRead);

            if (bytesRead < 100) 
            {
                // We ran out of data.
                break;
            }
        }

        byte[] plaintext = buffer.getArray();       
        return plaintext;

        }

Base64到字节转换方法:

private static byte[] Base64ToBytes(String code) {

        byte[] aesString = null;
        try 
        {
            aesString = Base64InputStream.decode(code);
        }
        catch (IOException ioe)
        {
        }
        return aesString;
    }

现在的问题是当我用上面的方法加密我的字符串时,我在字符串的末尾得到了填充的unicodes,这在服务器端是不能容忍的。

我知道这是由于PKCS5FormatterEngine及其正常情况,在使用此类时会在字符串末尾附加字符。

但是,如果我想使用AES / ECB方法加密和解密字符串,以及使用NoPadding也是如此。我知道ECB不是一种安全模式,只有服务器使用PHP并准备就绪,在Android和J2ME中运行良好。

请指导。如何绕过PKCS5FormatterEngine或加密而不进行任何填充。

更新

我尝试在Blackberry中使用Cipher类,因为我在Android和J2ME中使用它但在net_rim_api.jar中似乎不可用,即使我尝试下载bouncy castle jar文件和依赖类NoSuchAlogrithmException所以java.security jar(org.osgi.foundation) -1.0.0.jar),编译但是当我尝试运行它时停止说找到重复的类。在我为java.security保留的jar中有一些重复的类有一个问题。

如果你有解决方法,请告诉我。

答案更新: 我已使用完整的加密和解密代码更新我的代码,并检查答案以便更好地理解。

1 个答案:

答案 0 :(得分:3)

一般来说不确定这是否真的是一个答案,但在这种特殊情况下它可能会有所帮助,所以我会这样添加它。

如果没有一些填充,你不能真正使用AES,因为AES处理不希望假设你提供的数据是16字节的倍数。但是,如果您实际上总是提供16个字节的倍数的缓冲区,那么您可以使用以下代码加密数据:

        AESEncryptorEngine engine = new AESEncryptorEngine( key );
        for ( int j = 0; j < ciphertext.length - 15;  ) {
            engine.encrypt(plainText, j, ciphertext, j);
            j = j+16;
        }

那你怎么确定这个在另一端好吗?它可能会也可能不会这样做 - 它实际上取决于转移的内容。

但是,例如,如果您传递XML数据,那么您可以附加空格以使数据达到16字节边界,这些将由服务器解密为空格,然后通过解析忽略。您可以将冗余填充字节添加到各种文件格式中,并且将忽略填充,这一切都取决于正在处理的文件格式。

<强>更新

鉴于实际数据是JSON并且我认为JSON将忽略尾随空格,我将采用的方法是在加密之前将空格附加到JSON数据。

因此将JSON字符串转换为字节:

byte [] jsonBytes = jsonString.getBytes("UTF-8");

如果您需要,请填写此内容:

if ( (jsonBytes.length % 16) != 0 ) {
// Now pad this with spaces
}

并且您可以加密结果而无需担心填充字节。