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

本地存储并加密密码:纯QML替代C++插件实现可恢复式加密问询

嘿,这个需求确实挺贴合实际的——想要纯QML实现密码加解密,同时避开那些明显不安全的方案,我给你几个靠谱的方向:

可行的纯QML加密方案

1. 基于设备唯一标识生成加密密钥(无硬编码)

Qt QML本身提供了获取设备唯一标识的API,我们可以用它来生成加密密钥,完全不需要硬编码,也不会和平台二进制绑定。具体思路是:

  • 用Qt.system.uuid获取设备的唯一UUID(不同设备值不同)
  • 将UUID通过哈希算法(比如SHA-256)生成固定长度的对称加密密钥
  • 用这个密钥对明文密码进行对称加密(比如AES-256),加密后的内容可以存在本地存储里

示例代码:

import Qt.labs.crypto 1.0
import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    id: root
    visible: true

    SymmetricCipher {
        id: aesCipher
        algorithm: SymmetricCipher.Aes
        mode: SymmetricCipher.Cbc
        keyLength: SymmetricCipher.KeyLength256
    }

    // 生成AES密钥(基于设备UUID)
    function generateDeviceBoundKey() {
        const deviceUuid = Qt.system.uuid
        // 用SHA-256生成32字节的AES-256密钥
        return Qt.sha256(deviceUuid).toByteArray().slice(0, 32)
    }

    // 生成随机初始化向量(IV),每次加密都用新的IV更安全
    function generateRandomIV() {
        const iv = new Uint8Array(16)
        for (let i = 0; i < 16; i++) {
            iv[i] = Math.floor(Math.random() * 256)
        }
        return iv
    }

    // 加密明文密码
    function encryptPassword(plainPwd) {
        const key = generateDeviceBoundKey()
        const iv = generateRandomIV()
        
        aesCipher.key = key
        aesCipher.iv = iv
        aesCipher.open(SymmetricCipher.Encrypt)
        
        const encryptedBytes = aesCipher.process(plainPwd.toUtf8())
        aesCipher.close()
        
        // 将IV和密文一起Base64编码,方便存储
        return Qt.btoa(iv) + "|" + Qt.btoa(encryptedBytes)
    }

    // 解密密码
    function decryptPassword(encryptedStr) {
        const [ivBase64, cipherBase64] = encryptedStr.split("|")
        const key = generateDeviceBoundKey()
        const iv = Qt.atob(ivBase64).toByteArray()
        const cipherBytes = Qt.atob(cipherBase64).toByteArray()
        
        aesCipher.key = key
        aesCipher.iv = iv
        aesCipher.open(SymmetricCipher.Decrypt)
        
        const decryptedBytes = aesCipher.process(cipherBytes)
        aesCipher.close()
        
        return decryptedBytes.toString()
    }
}

2. 结合用户自定义PIN提升安全性

如果觉得仅靠设备UUID还不够安全,可以让用户设置一个PIN码,将UUID和PIN组合后生成密钥:

function generateKeyWithPin(deviceUuid, userPin) {
    const combinedSeed = deviceUuid + userPin
    return Qt.sha256(combinedSeed).toByteArray().slice(0, 32)
}

这种方式下,就算设备被盗,没有用户的PIN也无法解密密码,安全性更高。

3. 配合LocalStorage安全存储加密结果

加密后的密码可以存在QML的LocalStorage里,虽然LocalStorage本身不加密,但因为我们已经对密码做了强加密,就算数据库文件被获取,也只是一堆无法直接解读的乱码。

注意事项
  • Qt.labs.crypto是实验性模块,Qt 6版本已经更稳定,Qt 5版本使用前建议确认兼容性
  • 一定要给QML代码做混淆或编译处理,避免源码被轻易反编译(可以用Qt的qmlcompiler将QML编译为二进制资源)
  • 对称加密的IV必须随机生成并和密文一起存储,不要固定IV,否则会降低加密安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:03:27