使用AES算法进行加密和解密

巨人

我找到了有关加密和解密的教程,但是在尝试实施该教程时遇到了一个小问题。我想知道它是否是永久性的,但是String seedValue = "This Is MySecure";当我尝试将文本更改为其他文本时却出现一行,在解密时出现问题。这个代码在我一直想是否可以使用它来加密和解密密码的代码中不可更改。这是代码。

(使用AESHelper类,请在此处找到完整代码。)

public class MainActivity extends Activity {

    String seedValue = "This Is MySecure";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String normalText = "VIJAY";
        String normalTextEnc;

        try{
            normalTextEnc = AESHelper.encrypt(seedValue, normalText);
            String normalTextDec = AESHelper.decrypt(seedValue, normalTextEnc);
            TextView txe = new TextView(this);
            txe.setTextSize(14);
            txe.setText("Normal Text ::" + normalText + " \n Encrypted Value :: " + normalTextEnc + " \n Decrypted value :: " + normalTextDec);
            setContentView(txe);
        }catch(Exception e){
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


更新:

能够实现加密和解密,但是我遇到了另一个我不明白为什么会发生以及如何解决的问题。

错误说03-21 05:25:08.554: E/Exception(2109): pad block corrupted我从这里得到了这个网站的代码

更新:

垫块修复了另一个说:

03-24 02:31:33.131:E / Exception(1308):错误:06065064:数字信封程序:EVP_DecryptFinal_ex:错误解密

更新:这是我的代码,我按照建议进行操作,但是当我尝试解密加密的文件时仍然如此,反之亦然,加密后的我得到了例外。

package com.sample.camera;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import android.util.Base64;

public class EncodeDecodeAES {



    private final static String HEX = "0123456789ABCDEF";

    private final static int JELLY_BEAN_4_2 = 17;

    private final static byte[] key = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };




    // static {

    // Security.addProvider(new BouncyCastleProvider());

    // }



    public static String encrypt(String seed, String cleartext) throws Exception {

        byte[] rawKey = getRawKey(seed.getBytes());

        byte[] result = encrypt(rawKey, cleartext.getBytes());

        String fromHex = toHex(result);

        String base64 = new String(Base64.encodeToString(fromHex.getBytes(), 0));

        return base64;


    }




    public static String decrypt(String seed, String encrypted) throws Exception {

        byte[] seedByte = seed.getBytes();

        System.arraycopy(seedByte, 0, key, 0, ((seedByte.length < 16) ? seedByte.length : 16));

        String base64 = new String(Base64.decode(encrypted, 0));

        byte[] rawKey = getRawKey(seedByte);

        byte[] enc = toByte(base64);

        byte[] result = decrypt(rawKey, enc);

        return new String(result);


    }




    public static byte[] encryptBytes(String seed, byte[] cleartext) throws Exception {

        byte[] rawKey = getRawKey(seed.getBytes());

        byte[] result = encrypt(rawKey, cleartext);

        return result;


    }




    public static byte[] decryptBytes(String seed, byte[] encrypted) throws Exception {

        byte[] rawKey = getRawKey(seed.getBytes());

        byte[] result = decrypt(rawKey, encrypted);

        return result;


    }




    private static byte[] getRawKey(byte[] seed) throws Exception {

        KeyGenerator kgen = KeyGenerator.getInstance("AES"); // , "SC");

        SecureRandom sr = null;

        if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {

            sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");


        } else {

            sr = SecureRandom.getInstance("SHA1PRNG");


        }

        sr.setSeed(seed);

        try {

            kgen.init(256, sr);

            // kgen.init(128, sr);


        } catch (Exception e) {

            // Log.w(LOG, "This device doesn't suppor 256bits, trying 192bits.");

            try {

                kgen.init(192, sr);


            } catch (Exception e1) {

                // Log.w(LOG, "This device doesn't suppor 192bits, trying 128bits.");

                kgen.init(128, sr);


            }

        }

        SecretKey skey = kgen.generateKey();

        byte[] raw = skey.getEncoded();

        return raw;


    }




    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

        //Cipher cipher = Cipher.getInstance("AES"); // /ECB/PKCS7Padding", "SC");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        byte[] encrypted = cipher.doFinal(clear);

        return encrypted;


    }




    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // /ECB/PKCS7Padding", "SC");

        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

        byte[] decrypted = cipher.doFinal(encrypted);

        return decrypted;


    }




    public static String toHex(String txt) {

        return toHex(txt.getBytes());


    }




    public static String fromHex(String hex) {

        return new String(toByte(hex));


    }




    public static byte[] toByte(String hexString) {

        int len = hexString.length() / 2;

        byte[] result = new byte[len];

        for (int i = 0; i < len; i++)

            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();

        return result;

    }



    public static String toHex(byte[] buf) {
        if (buf == null)

            return "";

        StringBuffer result = new StringBuffer(2 * buf.length);

        for (int i = 0; i < buf.length; i++) {

            appendHex(result, buf[i]);

        }
        return result.toString();

    }




    private static void appendHex(StringBuffer sb, byte b) {

        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));


    }




}
初始化文件

除非我错过了什么,否则您的问题就在于数据输入的实际填充过程。

AES是一种分组密码,这意味着它可以一次处理大块数据。对于AES,块大小恰好是128位或16个字节。如果您的数据不是16字节的倍数,则当AES尝试处理最后一个块时,您将获得异常。

为了解决这个问题,发明了密码填充方案。密码填充方案本质上以某种方式“填充”您的数据,使其变为16字节的倍数,从而允许AES处理最后一块而不会出现问题。实际的AES标准填补方案是PKCS#5或PKCS#7填充(他们用不同的名字同样的事情)。

问题本质上就在于:

Cipher cipher = Cipher.getInstance("AES");

AESHelper课堂上。

仅使用算法名称(而不是algorithm / mode / padding调用getInstance()方法会导致Java推断特定的密码模式和填充方案。可以在下面指出的《Java密码体系结构(JCA)参考指南》中的“创建密码对象”下看到

如果仅指定一个转换名称,则系统将确定环境中是否存在所请求转换的实现,如果有多个,则返回一个首选转换。

如果未指定模式或填充,则使用模式和填充方案的提供程序特定的默认值。例如,对于DES,DES-EDE和Blowfish密码,SunJCE提供程序将ECB用作默认模式,将PKCS5Padding用作默认填充方案。

再次,相同的语句在android的Cipher javadoc页面中可见

如果省略mode和/或padding值,则将使用提供程序特定的默认值。

您想要的是:

AES / ECB / PKCS5填充

尽管可以说以上内容并不安全,但应使用以下内容:

AES / CBC / PKCS5填充

再加上随机IV生成,但这又是另一回事了。

更改行:

Cipher cipher = Cipher.getInstance("AES");

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

应该解决您的问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用Java进行AES加密和解密

来自分类Dev

如何使用RSA和AES算法加密和解密文件

来自分类Dev

AES加密和解密

来自分类Dev

加密和解密AES

来自分类Dev

在python和android中均通过AES算法进行加密和解密

来自分类Dev

使用C ++进行加密和解密

来自分类Dev

AES CTR加密和解密

来自分类Dev

Android:在Android中使用GCM模式进行AES加密和解密?

来自分类Dev

使用Java 8u20进行慢速AES GCM加密和解密

来自分类Dev

没有IV的情况下如何使用AES 128进行加密和解密?

来自分类Dev

如何在Elixir中使用AES CBC 128进行加密和解密

来自分类Dev

在某些情况下,使用AES ECB模式'BadPaddingException'进行加密和解密

来自分类Dev

使用crypto-js进行文件的AES加密和解密

来自分类Dev

如何在Elixir中使用AES CBC 128进行加密和解密

来自分类Dev

通过RSA算法对值进行加密和解密

来自分类Dev

如何使用phpseclib进行加密和使用AES算法使用Java进行解密

来自分类Dev

使用Golang和Ruby加密和解密AES

来自分类Dev

使用AES-128加密和解密字符串

来自分类Dev

使用AES加密和解密图像的正确方法

来自分类Dev

使用Spring Security进行AES加密/解密

来自分类Dev

AES / CBC / NoPadding加密和解密

来自分类Dev

快速的DES加密和解密算法

来自分类Dev

在C#中使用MachineKey进行加密和解密

来自分类Dev

使用C#中的证书进行加密和解密

来自分类Dev

Laravel使用C#进行加密和解密

来自分类Dev

使用JS和PHP进行RSA加密和解密

来自分类Dev

使用Java NetBeans对图像进行rsa加密和解密

来自分类Dev

使用phpseclib使用AES进行加密,并使用CryptoJS进行解密

来自分类Dev

使用CryptoJS进行AES加密并使用CodeIgniter进行解密

Related 相关文章

热门标签

归档