Python 相当于 java PBKDF2WithHmacSHA1
Python equivalent of java PBKDF2WithHmacSHA1
我的任务是构建一个 API 的消费者,它需要一个加密令牌,其种子值为 UNIX 时间。我看到的示例是使用我不熟悉的 Java 实现的,并且在阅读文档和其他堆栈文章后无法找到解决方案。
使用 javax.crypto.SecretKey
、javax.crypto.SecretKeyFactory
、javax.crypto.spec.PBEKeySpec
和 javax.crypto.spec.SecretKeySpec
协议,我需要生成类似于以下内容的令牌:
public class EncryptionTokenDemo {
public static void main(String args[]) {
long millis = System.currentTimeMillis();
String time = String.valueOf(millis);
String secretKey = "somekeyvalue";
int iterations = 12345;
String iters = String.valueOf(iterations);
String strToEncrypt_acctnum = "somevalue|" + time + "|" + iterations;
try {
byte[] input = strToEncrypt_acctnum.toString().getBytes("utf-8");
byte[] salt = secretKey.getBytes("utf-8");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey tmp = factory.generateSecret(new PBEKeySpec(secretKey.toCharArray(), salt, iterations, 256));
SecretKeySpec skc = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
String query = Base64.encodeBase64URLSafeString(cipherText);
// String query = cipherText.toString();
System.out.println("The unix time in ms is :: " + time);
System.out.println("Encrypted Token is :: " + query);
} catch (Exception e) {
System.out.println("Error while encrypting :" + e);
}
}
}
我应该使用内置库 hashlib
来实现这样的功能吗?我真的找不到以 iterations/salt 作为输入来实现 PBKDF2
加密的文档。我应该使用 pbkdf2
吗?对于模糊的问题,我深表歉意,我不熟悉加密过程,感觉即使知道正确的构造函数是什么也是朝着正确方向迈出的一步。
是的,Python 等价于 hashlib.pbkdf2_hmac
。例如这段代码:
from hashlib import pbkdf2_hmac
key = pbkdf2_hmac(
hash_name = 'sha1',
password = b"somekeyvalue",
salt = b"somekeyvalue",
iterations = 12345,
dklen = 32
)
print(key)
生成与您的 Java 代码相同的密钥。
但是,此代码的问题(如备忘录 中所述)是盐的使用。每个密码的盐应该是随机且唯一的。您可以使用 os.urandom
创建安全的随机字节,因此更好的示例是:
from hashlib import pbkdf2_hmac
from os import urandom
salt = urandom(16)
key = pbkdf2_hmac('sha1', b"somekeyvalue", salt, 12345, 32)
您可能还想增加迭代次数(我认为建议的最小次数是 10,000)。
剩下的代码很容易'translate'。
时间戳,用time.time
得到当前时间再乘以1000。
import time
milliseconds = str(round(time.time() * 1000))
对于编码,您可以使用 base64.urlsafe_b64encode
(它包括填充,但您可以使用 .rstrip(b'=')
将其删除)。
现在,对于加密部分,Python没有内置的加密模块,所以你必须使用第三方库。我推荐 pycryptodome
or cryptography
.
在这一点上,我必须警告您,您使用的 AES 模式非常弱。请考虑使用 CBC 或 CTR,或者最好使用 authenticated encryption 算法。
我的任务是构建一个 API 的消费者,它需要一个加密令牌,其种子值为 UNIX 时间。我看到的示例是使用我不熟悉的 Java 实现的,并且在阅读文档和其他堆栈文章后无法找到解决方案。
使用 javax.crypto.SecretKey
、javax.crypto.SecretKeyFactory
、javax.crypto.spec.PBEKeySpec
和 javax.crypto.spec.SecretKeySpec
协议,我需要生成类似于以下内容的令牌:
public class EncryptionTokenDemo {
public static void main(String args[]) {
long millis = System.currentTimeMillis();
String time = String.valueOf(millis);
String secretKey = "somekeyvalue";
int iterations = 12345;
String iters = String.valueOf(iterations);
String strToEncrypt_acctnum = "somevalue|" + time + "|" + iterations;
try {
byte[] input = strToEncrypt_acctnum.toString().getBytes("utf-8");
byte[] salt = secretKey.getBytes("utf-8");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey tmp = factory.generateSecret(new PBEKeySpec(secretKey.toCharArray(), salt, iterations, 256));
SecretKeySpec skc = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
String query = Base64.encodeBase64URLSafeString(cipherText);
// String query = cipherText.toString();
System.out.println("The unix time in ms is :: " + time);
System.out.println("Encrypted Token is :: " + query);
} catch (Exception e) {
System.out.println("Error while encrypting :" + e);
}
}
}
我应该使用内置库 hashlib
来实现这样的功能吗?我真的找不到以 iterations/salt 作为输入来实现 PBKDF2
加密的文档。我应该使用 pbkdf2
吗?对于模糊的问题,我深表歉意,我不熟悉加密过程,感觉即使知道正确的构造函数是什么也是朝着正确方向迈出的一步。
是的,Python 等价于 hashlib.pbkdf2_hmac
。例如这段代码:
from hashlib import pbkdf2_hmac
key = pbkdf2_hmac(
hash_name = 'sha1',
password = b"somekeyvalue",
salt = b"somekeyvalue",
iterations = 12345,
dklen = 32
)
print(key)
生成与您的 Java 代码相同的密钥。
但是,此代码的问题(如备忘录 os.urandom
创建安全的随机字节,因此更好的示例是:
from hashlib import pbkdf2_hmac
from os import urandom
salt = urandom(16)
key = pbkdf2_hmac('sha1', b"somekeyvalue", salt, 12345, 32)
您可能还想增加迭代次数(我认为建议的最小次数是 10,000)。
剩下的代码很容易'translate'。
时间戳,用
time.time
得到当前时间再乘以1000。import time milliseconds = str(round(time.time() * 1000))
对于编码,您可以使用
base64.urlsafe_b64encode
(它包括填充,但您可以使用.rstrip(b'=')
将其删除)。现在,对于加密部分,Python没有内置的加密模块,所以你必须使用第三方库。我推荐
pycryptodome
orcryptography
.
在这一点上,我必须警告您,您使用的 AES 模式非常弱。请考虑使用 CBC 或 CTR,或者最好使用 authenticated encryption 算法。