Java AES加密方法等价于MySQL AES_encrypt()函数
我想写一个AES加密方法,它应该相当于mysqlJava 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\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'))