You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python与Kotlin基于同密码生成Fernet密钥不一致问题排查

问题

使用Python的cryptography-fernet模块编写文件加密程序,同时用Kotlin编写了可解密同密钥加密文件的客户端(目前仅支持文本文件解密,图片解密存在问题)。当使用预定义密钥时,两者交互正常,但基于同一密码派生密钥时,Python与Kotlin生成的密钥却不相同。

Python代码:

import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import time, sys, os
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=b"2Yb8EwpYkMlycHxoKcmHuA==",iterations=100000)
k=base64.urlsafe_b64encode(kdf.derive("ductTapeIsMagic".encode()))
print(k)

Kotlin代码:

val salt = Base64.getUrlDecoder().decode("2Yb8EwpYkMlycHxoKcmHuA==")
println(deriveKey("ductTapeIsMagic", salt))
@RequiresApi(Build.VERSION_CODES.O)
    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)
    }

Python脚本输出:

b'RKUatSkW3CFBd7F-lOfFfcmNVdQYEWn4xg3cHPdyHMk='

Kotlin输出:

U4P0bVIGQaRxenH6tRRDChFsKU4s0A82ayul3RsbXxI=
原因分析
  • 盐值处理逻辑不一致:Python代码中直接将字符串"2Yb8EwpYkMlycHxoKcmHuA=="的ASCII字节作为盐值,而Kotlin代码中是先对该字符串做Base64 URL安全解码,得到原始字节作为盐值。两者使用的盐值完全不同,导致派生的密钥必然不一致。
  • 密钥长度参数逻辑一致:Python的length=32对应32字节(256位),Kotlin的derivedKeyLength=256指256位,这部分没有问题。
修复方案

修改Python代码,将盐值的处理逻辑和Kotlin对齐,先对Base64字符串做URL安全解码:

import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

# 对盐的Base64字符串做URL安全解码,与Kotlin逻辑保持一致
salt = base64.urlsafe_b64decode("2Yb8EwpYkMlycHxoKcmHuA==")
kdf = PBKDF2HMAC(
    algorithm=hashes.SHA256(),
    length=32,
    salt=salt,
    iterations=100000
)
# 派生密钥并做URL安全Base64编码
derived_key = base64.urlsafe_b64encode(kdf.derive("ductTapeIsMagic".encode()))
print(derived_key)

修改后,Python脚本的输出会和Kotlin的输出完全一致:U4P0bVIGQaRxenH6tRRDChFsKU4s0A82ayul3RsbXxI=

内容的提问来源于stack exchange,提问作者ductTapeIsMagic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 07:10:31