Fernet encryption/decryption 与 python 和科特林
Fernet encryption/decryption with python and kotlin
我有一个用 python 编写的项目。我使用密码学库来加密和解密数据。
我是如何在他们的 tutorial.
中显示的
这是我的 python 代码:
import base64
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
password = b"my password"
salt = os.urandom(16)
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend())
key = base64.urlsafe_b64encode(kdf.derive(password))
f = Fernet(key)
data = b"my data..."
token = f.encrypt(data)
然后为了解密我可以使用:
f.decrypt(token)
一切都在 python 中完美运行,但现在我需要在 kotlin 中做同样的事情。我发现了 fernet java-8 库,但我不知道如何以同样的方式使用它。
问题是我有两个工具:一个是用python写的,另一个我想用kotlin写的。这两种工具都旨在做同样的事情——python 一个用于桌面,kotlin 一个将是一个 android 应用程序。因此,它们的加密方式相同非常重要,这样在 python(桌面工具)中加密的文件可以在 kotlin(android 应用程序)中解密,反之亦然。
但我不知道如何编写类似的 kotlin 代码。
你看到有一个函数(或 class)叫做 PBKDF2HMAC
,还有 base64.urlsafe_b64encode
和其他函数。而且我不知道 kotlin 或 fernet 中的类似功能是什么 java-8.
那我应该怎么做呢?假设在 kotlin 中我必须使用我在 python.
中使用的密码和盐
谢谢!
在Java/Kotlin中,使用fernet-java8,用Python代码生成的令牌可以解密如下:
import java.security.SecureRandom
import java.util.Base64
import javax.crypto.spec.PBEKeySpec
import javax.crypto.SecretKeyFactory
import com.macasaet.fernet.Key
import com.macasaet.fernet.Token
import com.macasaet.fernet.StringValidator
import com.macasaet.fernet.Validator
import java.time.Duration
import java.time.temporal.TemporalAmount
...
// Data from encryption
val salt = Base64.getUrlDecoder().decode("2Yb8EwpYkMlycHxoKcmHuA==")
val token = Token.fromString("gAAAAABfoAmp7C7IWVgA5urICEIspm_MPAGZ-SyGnPEVUBBNerWQ-K6mpSoYTwRkUt3FobyAFHbYfhNtiGMe_96yyLvUoeLIIg==");
// Derive Fernet key
val key = deriveKey("my password", salt)
val fernetKey = Key(key)
// Decrypt
val validator: Validator<String> = object : StringValidator {
override fun getTimeToLive(): TemporalAmount {
return Duration.ofHours(24)
}
}
val data = token.validateAndDecrypt(fernetKey, validator)
println(data) // my data...
与:
fun deriveKey(password: String, salt: ByteArray): String {
val iterations = 100000
val derivedKeyLength = 256
val spec = PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength)
val secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val key = secretKeyFactory.generateSecret(spec).encoded
return Base64.getUrlEncoder().encodeToString(key)
}
这里 Fernet 密钥是使用密钥导出函数 PBKDF2. PBKDF2 expects various input parameters, such as a password, a digest, a salt, an iteration count and the desired key length. In the posted example the key is returned Base64url 编码导出的。
对于解密,必须使用与加密相同的参数。由于盐通常(如发布的代码中)在加密过程中随机生成,因此必须将其与密文一起传递给解密方(注意:盐不是秘密)。
验证器将 time-to-live(默认 60 秒)设置为 24 小时,详情请参阅 here。
在发布的 Python 代码中,必须添加盐的导出,例如通过 Base64url 编码它类似于密钥和令牌(并为简单起见打印它)。实际上,salt和token也可以在加密时串接,解密时分开。
更新:
加密部分类似:
// Generate salt
val salt = generateSalt()
println(Base64.getUrlEncoder().encodeToString(salt))
// Derive Fernet key
val key = deriveKey("my password", salt)
val fernetKey = Key(key)
// Encrypt
val data = "my data..."
val token = Token.generate(fernetKey, data)
println(token.serialise()) // the Base64url encoded token
和
fun generateSalt(): ByteArray {
val random = SecureRandom()
val salt = ByteArray(16)
random.nextBytes(salt)
return salt
}
我有一个用 python 编写的项目。我使用密码学库来加密和解密数据。 我是如何在他们的 tutorial.
中显示的这是我的 python 代码:
import base64
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
password = b"my password"
salt = os.urandom(16)
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend())
key = base64.urlsafe_b64encode(kdf.derive(password))
f = Fernet(key)
data = b"my data..."
token = f.encrypt(data)
然后为了解密我可以使用:
f.decrypt(token)
一切都在 python 中完美运行,但现在我需要在 kotlin 中做同样的事情。我发现了 fernet java-8 库,但我不知道如何以同样的方式使用它。
问题是我有两个工具:一个是用python写的,另一个我想用kotlin写的。这两种工具都旨在做同样的事情——python 一个用于桌面,kotlin 一个将是一个 android 应用程序。因此,它们的加密方式相同非常重要,这样在 python(桌面工具)中加密的文件可以在 kotlin(android 应用程序)中解密,反之亦然。
但我不知道如何编写类似的 kotlin 代码。
你看到有一个函数(或 class)叫做 PBKDF2HMAC
,还有 base64.urlsafe_b64encode
和其他函数。而且我不知道 kotlin 或 fernet 中的类似功能是什么 java-8.
那我应该怎么做呢?假设在 kotlin 中我必须使用我在 python.
中使用的密码和盐谢谢!
在Java/Kotlin中,使用fernet-java8,用Python代码生成的令牌可以解密如下:
import java.security.SecureRandom
import java.util.Base64
import javax.crypto.spec.PBEKeySpec
import javax.crypto.SecretKeyFactory
import com.macasaet.fernet.Key
import com.macasaet.fernet.Token
import com.macasaet.fernet.StringValidator
import com.macasaet.fernet.Validator
import java.time.Duration
import java.time.temporal.TemporalAmount
...
// Data from encryption
val salt = Base64.getUrlDecoder().decode("2Yb8EwpYkMlycHxoKcmHuA==")
val token = Token.fromString("gAAAAABfoAmp7C7IWVgA5urICEIspm_MPAGZ-SyGnPEVUBBNerWQ-K6mpSoYTwRkUt3FobyAFHbYfhNtiGMe_96yyLvUoeLIIg==");
// Derive Fernet key
val key = deriveKey("my password", salt)
val fernetKey = Key(key)
// Decrypt
val validator: Validator<String> = object : StringValidator {
override fun getTimeToLive(): TemporalAmount {
return Duration.ofHours(24)
}
}
val data = token.validateAndDecrypt(fernetKey, validator)
println(data) // my data...
与:
fun deriveKey(password: String, salt: ByteArray): String {
val iterations = 100000
val derivedKeyLength = 256
val spec = PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength)
val secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val key = secretKeyFactory.generateSecret(spec).encoded
return Base64.getUrlEncoder().encodeToString(key)
}
这里 Fernet 密钥是使用密钥导出函数 PBKDF2. PBKDF2 expects various input parameters, such as a password, a digest, a salt, an iteration count and the desired key length. In the posted example the key is returned Base64url 编码导出的。
对于解密,必须使用与加密相同的参数。由于盐通常(如发布的代码中)在加密过程中随机生成,因此必须将其与密文一起传递给解密方(注意:盐不是秘密)。
验证器将 time-to-live(默认 60 秒)设置为 24 小时,详情请参阅 here。
在发布的 Python 代码中,必须添加盐的导出,例如通过 Base64url 编码它类似于密钥和令牌(并为简单起见打印它)。实际上,salt和token也可以在加密时串接,解密时分开。
更新:
加密部分类似:
// Generate salt
val salt = generateSalt()
println(Base64.getUrlEncoder().encodeToString(salt))
// Derive Fernet key
val key = deriveKey("my password", salt)
val fernetKey = Key(key)
// Encrypt
val data = "my data..."
val token = Token.generate(fernetKey, data)
println(token.serialise()) // the Base64url encoded token
和
fun generateSalt(): ByteArray {
val random = SecureRandom()
val salt = ByteArray(16)
random.nextBytes(salt)
return salt
}