Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AES加密方法等价于MySQL AES_encrypt()函数_Java_Mysql_Encryption_Aes - Fatal编程技术网

Java AES加密方法等价于MySQL AES_encrypt()函数

Java AES加密方法等价于MySQL AES_encrypt()函数,java,mysql,encryption,aes,Java,Mysql,Encryption,Aes,我想写一个AES加密方法,它应该相当于mysqlAES\u encrypt 我试着写,但不正确,因为mysql没有提供正确的数据 我该怎么做才能使它正确 Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); byte[] encryptedTextBytes = cipher.doFinal(message .getBytes("UTF-8")); String k = ne

我想写一个AES加密方法,它应该相当于mysql
AES\u encrypt

我试着写,但不正确,因为mysql没有提供正确的数据

我该怎么做才能使它正确

Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec); 
byte[] encryptedTextBytes = cipher.doFinal(message .getBytes("UTF-8")); 
String k = new String(encryptedTextBytes); 
System.out.println("KKKKK"+k);

我建议使用Java加密API。BC被广泛认为是一个伟大的加密工具包,如果您愿意,它可以作为加密提供者插入JavaAPI。我知道这并不能直接回答你的问题,但我从未见过有人对Bouncy Castle有任何问题。

MySQL的AES实现让很多人头疼。这主要是因为MySQL是如何处理加密密钥的。加密密钥被分成16个字节的块,MySQL将把一个块中的字节与前一个块中的字节进行异或运算。如果用户提供的密钥的长度恰好小于16字节,则该密钥基本上用空字节填充,最多可达16字节。这就是MySQL的aes_encrypt()处理密钥的方式

还将通过使用PKCS7填充数据来处理要加密的值。您可以了解PKCS7@的所有内容,但它所做的只是填充输入数据,使其位于16字节块中。填充数据的字节数等于将要添加的填充字节数

长话短说,您需要像MySQL那样处理加密密钥,还需要使用PKCS7填充输入数据

有关Java中的示例代码,请参阅Michael Simmons的以下文章:

几年前,我不得不使用BouncyCastle进行此操作。正如Alen Puzic在回答中所述,这两个问题是mysql密钥生成和PKCS7填充。BouncyCastle将使用其
PaddedBufferedBlockCipher
为您处理填充,但您需要自己生成密钥。下面是执行此操作的代码:

/**
 * Use password to generate a MySQL AES symmetric key
 * @param passwd Password String to use.
 * @param keyLength Must be evenly divisible by 8.
 * @return Key for use with MySQL AES encrypt/decrypt fuctions.
 */
public static KeyParameter getMySqlAESPasswdKey(String passwd, int keyLength) {
    byte[] pword = passwd.getBytes();
    byte[] rawKey = new byte[keyLength/8];
    int j = 0;
    for (int i = 0; i < pword.length; i++, j++) {

        if(j==rawKey.length) {
            j = 0;
        }
        rawKey[j] = pword[i];
    }

    return new KeyParameter(rawKey);
}

感谢您的深入了解,终于正确了,下面是一个简单的python版本:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import codecs


def encrypt(data, key):
    key = key + b"\0" * (16 - len(key) % 16)
    padder = padding.PKCS7(128).padder()
    data = padder.update(data) + padder.finalize()
    alg = algorithms.AES(key)
    cipher = Cipher(alg, modes.ECB(), default_backend())
    encryptor = cipher.encryptor()
    ct = encryptor.update(data) + encryptor.finalize()
    return ct


if __name__ == '__main__':
    enc = encrypt(b'123456', b'1234567890')
    print(codecs.encode(enc, 'hex'))

请先发布不起作用的当前代码。Cipher Cipher=Cipher.getInstance(“AES”);cipher.init(cipher.ENCRYPT_模式,keySpec);byte[]encryptedTextBytes=cipher.doFinal(message.getBytes(“UTF-8”);字符串k=新字符串(encryptedTextBytes);System.out.println(“kkkk”+k)@用户2888996在以后编辑您的问题以添加其他详细信息,如代码。这一次我为你添加了它。谢谢,我是新来的,不知道如何正确发布。将来我会记得
String k=新字符串(encryptedTextBytes)
不正确。AES密码的输出不是字符数据(理想情况下,它与随机数据无法区分),不太可能表示有效的UTF-8码点。如果您想将密文存储为
字符串
,则应将字节数组编码为Base64或Hex。对不起,我必须对此进行否决。正如你承认的,这不是问题的答案。我相信一旦发现问题,BouncyCastle就可以使用,但对于许多JCE提供商(包括Oracle提供商)来说,情况可能也是如此
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import codecs


def encrypt(data, key):
    key = key + b"\0" * (16 - len(key) % 16)
    padder = padding.PKCS7(128).padder()
    data = padder.update(data) + padder.finalize()
    alg = algorithms.AES(key)
    cipher = Cipher(alg, modes.ECB(), default_backend())
    encryptor = cipher.encryptor()
    ct = encryptor.update(data) + encryptor.finalize()
    return ct


if __name__ == '__main__':
    enc = encrypt(b'123456', b'1234567890')
    print(codecs.encode(enc, 'hex'))