在python中实现java jasypt的pbewithhmacsha512andaes256

在python中实现java jasypt的pbewithhmacsha512andaes256,java,python,cryptography,hmac,jasypt,Java,Python,Cryptography,Hmac,Jasypt,我正在尝试用python加密密码,并使用through在JavaSpringBoot应用程序中解密密码 我到目前为止所做的事情 为了简单起见,我使用了零盐和固定iv 我已经编写了python脚本,使用hselvarajan的 以同样的方式运行它 我在jasypt存储库中编写了一个单元测试来解密 看见 以同样的方式运行它 问题:上述设置在python和java中产生不同的结果 Python输出:mdawmdawmkwswh+Ku37n7ddfj0ayxp8= Java输出:mdawmda

我正在尝试用python加密密码,并使用through在JavaSpringBoot应用程序中解密密码

我到目前为止所做的事情

  • 为了简单起见,我使用了零盐和固定iv
  • 我已经编写了python脚本,使用hselvarajan的 以同样的方式运行它
  • 我在jasypt存储库中编写了一个单元测试来解密 看见 以同样的方式运行它
问题:上述设置在python和java中产生不同的结果

  • Python输出:mdawmdawmkwswh+Ku37n7ddfj0ayxp8=
  • Java输出:mdawmdawmdawmatqafbtuxf+f5qzc8qifc=
我所知道的

  • 失败的原因是没有在python中使用正确的键。添加其他日志时,错误为
    EncryptionOperationNotPossibleException: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    
  • PBEWITHmACSHA512Andaes256使用pkcs12密钥派生函数。 我不明白HMAC在哪里使用
  • 我也尝试过使用folling实现,但没有效果。我在所有这些中都得到了“”错误。
    • Cryptodome.Protocol.KDF HKDF 我不明白这里在哪里使用迭代
我想要一些关于我做错了什么的指导。任何帮助,任何指点都将不胜感激


在Cryptodome的PBKDF2和AES之后更新 下面是python脚本

import sys
import base64
from Cryptodome.Cipher import AES
from Cryptodome.Hash import SHA512
from Cryptodome.Protocol.KDF import PBKDF2
from Cryptodome.Util.Padding import pad

iterations          = 10000
password             = b'test1'
plaintext_to_encrypt = b'password1'
salt                 = b'0000000000000000'
iv                   = b'0000000000000000'

# -----------------------------------------------------------------------------
# Main execution
# -----------------------------------------------------------------------------
keys = PBKDF2(password, salt, 64, count=iterations, hmac_hash_module=SHA512)
aes_key = keys[:32]

cipher = AES.new(aes_key, AES.MODE_CBC, iv)
ct_bytes = cipher.encrypt(pad(plaintext_to_encrypt, AES.block_size))
encrypted = base64.b64encode(ct_bytes).decode('utf-8')

# Since we selt the salt to be zero's,
# jasypt needs only the iv + encrypted value,
# not the salt + iv + encrypted
result = encrypted

# Python output : 6tCAZbswCh9DZ1EK8utRuA==
# Java output   : C2oB8G27F/4XmqrMLxCIVw==
print(result)

及其产出

python2.7 test-PBEWITHHMACSHA512ANDAES_256-2.py
6tCAZbswCh9DZ1EK8utRuA==
我尝试在java中使用

mvn清洁测试-Dtest=org.jasypt.encryption.pbe.PBEWITHHMACSHA512ANDAES_256EncryptorTest
[...]
运行org.jasypt.encryption.pbe.pbewithhmacsha512andaes256encryptortest
测试附件:C2oB8G27F/4XmqrMLxCIVw==

错误:javax.crypto.BadPaddingException:给定的最后一个块未正确填充。如果在解密过程中使用了坏密钥,则可能会出现此类问题。测试运行:1,失败:0,错误:1,跳过:0,经过的时间:0.524秒
PBEWITHHMACSHA512ANDAES_256
应用PBKDF2生成密钥。使用AES-256、CBC执行加密

应用(最初)使用的posted Jasypt test函数,该函数为salt创建一个随机IV。该函数生成一个由16个零字节组成的salt

要实现您正在寻找的Python函数,最好使用固定的IV,例如with。为salt提供相应的功能(具有相同的功能,但自1.9.2起不再推荐)
StringFixedSaltGenerator
StringFixedIvGenerator
默认情况下使用UTF-8对传递的字符串进行编码(但可以指定另一种编码),以便salt(或IV)
0000000000000000000000
是十六进制编码的
0x30303030

注意,固定盐和IV只能用于测试。实际上,每次加密都必须使用新的随机salt和新的随机IV。由于salt和IV不是秘密的,它们通常在字节级别与密文连接(例如,按照salt、IV、密文的顺序),并发送给接收者,接收者分离这些部分并使用它们进行解密

如果双方使用相同的参数(特别是相同的salt和IV),那么使用Python加密和Java解密就可以了

使用Python加密(PyCryptodome):

使用Java(Jasypt)解密:


顺便说一下,如果有人仍然在寻找这个答案,但随机盐和IV,似乎他们是按顺序附加到密码文本。以下是与PBEWithHMACSHA512AndAES_256兼容的加密/解密解决方案:

从base64导入B64解码,B64编码
从cryptography.fernet导入fernet
从cryptography.hazmat.primitives导入哈希
从cryptography.hazmat.primitives.kdf.pbkdf2导入PBKDF2HMAC
从cryptography.hazmat.backends导入默认\u后端
从cryptography.hazmat.primitives.padding导入PKCS7
从cryptography.hazmat.primitives.ciphers导入密码、算法、模式
钥匙=b‘我最棒的钥匙’
def使用_hmac_sha512_aes_256(obj:str)->str解密_pbe_:
#从重新生成密钥
加密的_obj=b64解码(obj)
salt=加密的对象[0:16]
iv=加密对象[16:32]
cypher_text=加密的_obj[32:]
kdf=PBKDF2HMAC(hashes.SHA512(),32,salt,1000,backend=default_backend())
key=kdf.derivate(key)
#解密
cipher=cipher(algorithms.AES(key),modes.CBC(iv),backend=default_backend())
decryptor=cipher.decryptor()
padded_text=decryptor.update(cypher_text)+decryptor.finalize()
#除去填充物
unpadder=PKCS7(128).unpadder()
clear_text=unpadder.update(填充的_text)+unpadder.finalize()
返回明文。解码()
def用aes 256加密pbe(对象:str,salt:bytes=None,iv:bytes=None)->str:
#生成密钥
盐=盐或铀氧化物(16)
iv=iv或os.urandom(16)
kdf=PBKDF2HMAC(hashes.SHA512(),32,salt,1000,backend=default_backend())
key=kdf.derivate(key)
#焊盘数据
padder=PKCS7(128).padder()
data=padder.update(obj.encode())+padder.finalize()
#加密
cipher=cipher(algorithms.AES(key),modes.CBC(iv),backend=default_backend())
encryptor=cipher.encryptor()
cypher_text=encryptor.update(数据)+encryptor.finalize()
返回b64encode(salt+iv+cypher_文本)
然后,您可以使用Jasypt的base64输出直接使用它:

>>使用\u-hmac\u-sha512\u-aes\u 256解密\u-pbe\u(使用\u-hmac\u-sha512\u-aes\u 256(“你好世界”)加密\u-pbe\u)
“你好,世界”

Jasypt测试函数使用PBKDF2生成密钥。独立于此,生成随机IV。使用生成的密钥和IV,使用AES-256、CBC对明文进行加密。所有使用过的组件(PBKDF2、AES-CBC)都提供了Python中的大多数加密库,例如PyCryptodome,请参见和,因此我并不需要hselvarajan的pkcs12kdf。我是在我
EncryptionOperationNotPossibleException: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
self.aes_key = HKDF(master = self.password, key_len = 32, salt = self.salt, hashmod = SHA512, num_keys = 1)
import sys
import base64
from Cryptodome.Cipher import AES
from Cryptodome.Hash import SHA512
from Cryptodome.Protocol.KDF import PBKDF2
from Cryptodome.Util.Padding import pad

iterations          = 10000
password             = b'test1'
plaintext_to_encrypt = b'password1'
salt                 = b'0000000000000000'
iv                   = b'0000000000000000'

# -----------------------------------------------------------------------------
# Main execution
# -----------------------------------------------------------------------------
keys = PBKDF2(password, salt, 64, count=iterations, hmac_hash_module=SHA512)
aes_key = keys[:32]

cipher = AES.new(aes_key, AES.MODE_CBC, iv)
ct_bytes = cipher.encrypt(pad(plaintext_to_encrypt, AES.block_size))
encrypted = base64.b64encode(ct_bytes).decode('utf-8')

# Since we selt the salt to be zero's,
# jasypt needs only the iv + encrypted value,
# not the salt + iv + encrypted
result = encrypted

# Python output : 6tCAZbswCh9DZ1EK8utRuA==
# Java output   : C2oB8G27F/4XmqrMLxCIVw==
print(result)

python2.7 test-PBEWITHHMACSHA512ANDAES_256-2.py
6tCAZbswCh9DZ1EK8utRuA==
mvn clean test -Dtest=org.jasypt.encryption.pbe.PBEWITHHMACSHA512ANDAES_256EncryptorTest

[...]

Running org.jasypt.encryption.pbe.PBEWITHHMACSHA512ANDAES_256EncryptorTest
Test encr: C2oB8G27F/4XmqrMLxCIVw==
Error: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.524 sec <<< FAILURE!
test1(org.jasypt.encryption.pbe.PBEWITHHMACSHA512ANDAES_256EncryptorTest)  Time elapsed: 0.522 sec  <<< ERROR!
org.jasypt.exceptions.EncryptionOperationNotPossibleException
    at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.decrypt(StandardPBEByteEncryptor.java:1173)
    at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:738)
    at org.jasypt.encryption.pbe.PBEWITHHMACSHA512ANDAES_256EncryptorTest.test1(PBEWITHHMACSHA512ANDAES_256EncryptorTest.java:27)


Results :

Tests in error:
  test1(org.jasypt.encryption.pbe.PBEWITHHMACSHA512ANDAES_256EncryptorTest)

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  8.648 s
[INFO] Finished at: 2020-06-24T17:40:04+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project jasypt: There are test failures.
[ERROR]
[ERROR] Please refer to /space/openbet/git/github-jasypt-jasypt/jasypt/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
import base64
from Cryptodome.Cipher import AES
from Cryptodome.Hash import SHA512
from Cryptodome.Protocol.KDF import PBKDF2
from Cryptodome.Util.Padding import pad

# Key generation (PBKDF2)
iterations           = 10000
password             = b'test1'
plaintext_to_encrypt = b'password1'
salt                 = b'5432109876543210'
iv                   = b'0123456789012345'
key = PBKDF2(password, salt, 32, count=iterations, hmac_hash_module=SHA512)

# Encryption (AES-256, CBC)
cipher = AES.new(key, AES.MODE_CBC, iv)
ct_bytes = cipher.encrypt(pad(plaintext_to_encrypt, AES.block_size))
encrypted = base64.b64encode(ct_bytes).decode('utf-8')

print(encrypted) # Output: kzLd5qPlCLnHq5sT7LOXzQ==
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("test1");
encryptor.setSaltGenerator(new StringFixedSaltGenerator("5432109876543210"));
encryptor.setIvGenerator(new StringFixedIvGenerator("0123456789012345"));
encryptor.setKeyObtentionIterations(10000);
encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
    
String decryptedMsg = encryptor.decrypt("kzLd5qPlCLnHq5sT7LOXzQ==");
System.out.println("Test decr: " + decryptedMsg); // Output: Test decr: password1