0

我是黑莓开发新手,必须使用 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 到 Bytes 的转换方法:

private static byte[] Base64ToBytes(String code) {

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

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

我知道这是由于 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 中几乎没有重复的类有问题。

如果您对此有解决方案,请告诉我。

更新答案: 我已经用完整的加密和解密代码更新了我的代码,并检查了答案以获得更好的理解。

4

1 回答 1

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
}

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

于 2013-09-17T12:41:16.243 回答