黑莓的NoPadding加密AES [英] AES encryption with NoPadding in blackberry

查看:168
本文介绍了黑莓的NoPadding加密AES的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是黑莓开发的新手,要用AES / ECB / NoPadding完成加密和解密任务。



加密方法:



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


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

//创建用于加密数据的AES密钥。
//这将使用尽可能多的keyData
//创建一个AES密钥。


if((data.length%16)!= 0){
StringBuffer buffer = new StringBuffer(message);
int moduleOut = data.length%16;
int padding = 16 - moduleOut; (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();
返回cbytes;

}

解密方法:

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

// String base64EncodedData = new String(base64EncodedData);

byte [] cipherText = Base64ToBytes(new String(base64EncodedData));
//首先,再次创建AESKey。
AESKey key = new AESKey(keyData);

//现在,创建解密器引擎。
AESDecryptorEngine engine = new AESDecryptorEngine(key);

//创建BlockDecryptor来隐藏解密细节。
ByteArrayInputStream input = new ByteArrayInputStream(cipherText);
BlockDecryptor decryptor = new BlockDecryptor(引擎,输入);

//现在,读入数据。
byte [] temp = new byte [100];
DataBuffer buffer = new DataBuffer();

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

if(bytesRead< 100)
{
//我们用完了数据。
break;
}
}

byte [] plaintext = buffer.getArray();
返回明文;

}

Base64 to Bytes convert方法:

  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中的几个重复类。



如果您有解决方案,请通知我。



更新为答案: / strong>
我已经用完整的加密和解密代码更新了我的代码,并检查答案以便更好地理解。

解决方案

p>不知道这是一般的答案,但是在这种具体情况下可能会有所帮助,所以我正在添加它。



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

  AESEncryptorEngine引擎=新的AESEncryptorEngine(key); (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){
//现在用空格填充
}

,您可以加密结果,而不用担心填充字节。


I am new to blackberry development and got to complete a task of encryption and decryption with AES/ECB/NoPadding. I used below code, from internet.

Encryption method:

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;

    }

Decryption method:

    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 to Bytes convert method:

private static byte[] Base64ToBytes(String code) {

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

Now the problem is when i encrypt my string with above method i get padded unicodes at the end of the string, which is not tolerable at Server side.

I know it is due to PKCS5FormatterEngine and its normal to have characters appended at end of the string while using this class.

But what if i want to encrypt and decrypt string with AES/ECB method and that too with NoPadding. I know ECB is not a secure mode and all that but server is with PHP and ready, works great in Android, and J2ME.

Please guide. How to bypass PKCS5FormatterEngine or encrypt without any padding.

Update:

I tried to use Cipher class in Blackberry as i used in Android and J2ME but it seems unavailable in net_rim_api.jar, even i tried downloading bouncy castle jar file and dependent class NoSuchAlogrithmException so java.security jar (org.osgi.foundation-1.0.0.jar), compiles but when i try to run it stops saying duplicate classes found. It has a problem with few duplicate classes in jar i have kept for java.security.

If you have solution towards this, please let me know.

Update for Answer: I have update my code with full encryption and decryption code and also check the answer for better understanding.

解决方案

Not sure this is really an answer in general, but it might help in this specific case, so I am adding it as such.

You can't really use AES without some padding, because the AES processing does not wish to assume the data you supply will be a multiple of 16 bytes. However if you actually always supply a buffer that is a multiple of 16 bytes, then you can just encrypt your data with code like this:

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

So how do you make sure this works OK at the other end? It may or may not be possible to do this - it actually depends on what is being transferred.

But if, for example, you were passing XML data, then you can append spaces to make the data up to a 16 byte boundary and these will be decrypted as spaces by the Server, and then ignored by the parsing. You can add redundant padding bytes to a variety of file formats and the padding will be ignored, it all depends on the file format being processed.

Update

Given that the actual data is JSON and that I believe that JSON will ignore trailing spaces, the approach I would take is append spaces to the JSON data before encrypting it.

So convert the JSON string to bytes:

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

pad this if you need too:

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

and you can encrypt the result with no worries about padding bytes.

这篇关于黑莓的NoPadding加密AES的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆