将字符串转换为128位的AES密钥 [英] Turn String to 128-bit key for AES

查看:390
本文介绍了将字符串转换为128位的AES密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想输入自己的String变量,然后将其转换为AES算法的加密/解密密钥。我已经尝试过许多已知的方法,如UTF-8,base64,一些方法做转换字节串,反之亦然。尽管所有这些都是正常工作的,但是其中一些工作不正确,所有这些都以字节为单位,但是我想要的是输入helloWorld,并返回一个128位的AES密钥。我使用的任何东西都是无效的密钥长度,因为字节不准确。
我需要做什么来获取正确的字节?此外,我想澄清一点,我想要String而不是一个char数组,因为我想让它作为一个函数在我的程序中,以便用户可以随意改变密钥,如果它被妥协。

I want to enter my own String variable to then turn it into a key for encryption/decryption for AES algorithm. I have tried many known ways such as UTF-8, base64, some methods doing conversion byte-string and vice versa and some other. Although it's true that all of them work even with some of them not working accurately, all of them turn the string in bytes, but what i want is to enter something like "helloWorld" and get back a 128-bit key for AES. Anything i use it goes for "Invalid key length" since the bytes are not accurate. What do i need to do to get the correct bytes? Also i want to clarify that i want String and not an array of char since i want to make it as a function in my programm later so that the user can change the key at will should it be compromised.

更新:我编辑了这个例子,这个我到目前为止,仍然抛出关于参数和密钥长度的例外,但是

UPDATE: i edited the example and this i what i have so far, still throws exception about parameters and key length though

    public class SHAHashingExample
{
    private static byte[] keyValue;

    public static void main(String[] args)throws Exception
    {
        String password = "123456";

        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes());

        byte byteData[] = md.digest();
        keyValue = md.digest();

        //convert the byte to hex format method 1
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < byteData.length/2; i++) {
         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        }

        System.out.println("Hex format : " + sb.toString());

        //convert the byte to hex format method 2
        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<byteData.length/2;i++) {
            String hex=Integer.toHexString(0xff & byteData[i]);
            if(hex.length()==1) hexString.append('0');
            hexString.append(hex);
        }
        System.out.println("Hex format : " + hexString.toString());

        String k = "hello world";
        String f = encrypt(k);
        System.out.println(f);
        String j = decrypt(f);
        System.out.println(j);
    }

    public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }

    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(keyValue, "AES");
        return key;
    }
}


推荐答案

strong>更新2:
证明您对Java Cipher功能的许多组件的使用不会发生。看这个其他SO答案。

UPDATE 2: Turns out your usage of many components of the Java Cipher capabilities are not spot on. Look here at this other SO answer.

Java AES并使用我自己的密钥

更新1:
要获取256位值可以使用下面的例子减到128位,这里是你可能想尝试的:

UPDATE 1: To get the 256 bit value down to 128 bits using the example below, here is what you may want to try:

// After you already have generated the digest
byte[] mdbytes = md.digest();
byte[] key = new byte[mdbytes.length / 2];

for(int I = 0; I < key.length; I++){
    // Choice 1 for using only 128 bits of the 256 generated
    key[I] = mdbytes[I];

    // Choice 2 for using ALL of the 256 bits generated
    key[I] = mdbytes[I] ^ mdbytes[I + key.length];
}

// Now use key as the input key for AES

ORIGINAL:
以下是使用内置的java API在某些数据字节上执行SHA哈希的一个很好的例子。

ORIGINAL: Here is a great example of using the built-in java APIs for performing a SHA hash on some data bytes.

http://www.mkyong.com/java/java -sha-hashing-example /

Java具有内置的执行多种不同哈希类型的功能,您应该尽量利用一种,而不是试图自己写一个。也许最广泛使用的哈希函数是SHA版本。有一些版本可以输出一个128,256和512位的哈希输出。

Java has built-in capability to perform multiple differing hash types, and you really should try to take advantage of one, instead of trying to write one yourself. Perhaps the most widely used hash functions are the SHA versions. There are versions that can output a 128, 256, and 512 bit hash output.

你所要求的是所有的技术性,正是如何使用你的密码通常工作。该系统从来没有真正存储你的实际的密码,而是HASH。当用户输入密码时,系统将对输入的内容执行实时哈希,并将实时生成的散列与存储的散列进行比较。这不是让我们说使用该哈希作为对称加密的实际键组件的添加步骤。一般来说,GOOD哈希确实可以生成用于实际对称加密/解密的DECENT密钥材料。

What you are asking for, is in all technicality exactly how logging into a system using your password generally works. the system never truly stores your actual textual password, but rather the HASH to it. When you, the user, enters your password, the system performs a live hash of what you entered and compares the live generated hash with the stored hash. This does not go the added step of lets say using that hash as an actual key component for a symmetric encryption. In general a GOOD hash can indeed generate DECENT key material for use in actual symmetric encryption / decryption.

这篇关于将字符串转换为128位的AES密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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