##HarmonyOS 应用开发##
先上一下效果
前置准备:有一个演示.txt文件,我提前下载到了手机上,里面的内容是“测试内容,今天天气很好”。
进入“文件加密”页面,选择文件后,显示文件内容,输入密钥后,点击加密,显示加密后内容,并可以保存到文件里
进入“文件解密”页面,选择文件后,显示加密后的文件内容,输入密钥,点击解密,显示解密后内容,并可以保存到文件里
两个页面的截图如下:
)
相关技术实现思路如下:
一、SM4加密解密
大部分的代码官网都有,我这里先介绍一下我的开发中踩坑的记录
如果看官方文档里的代码,你会发现,他对于加密解密的演示,是直接把加密后的结果,扔给解密的代码的。
如果直接拿来用的话,问题是……encryptText,他不是一个string,而是cryptoFramework.DataBlob
如果要把这个解密后的内容,显示给用户看的话,看文档的意思就是encryptText.data.toString(),所以我就通过encryptText.data.toString()获取了加密后的文字内容,并保存到了文件里。
但是解密的时候,我按照文档里的代码,输入这个解密后的文字内容,但是提示错误,是doFinal()这一步的报错,但是我在文档里都看不到具体这个报错对应的错误原因是什么……
后来在开发群里,有幸得到了大佬的指点
大佬的原话如下: “你输出的是hex 那么 在入参的时候也需要将hex转换成unit8Array 类型要匹配”
“不能输出的是hex 解密的时候又传入了base64但是还用hex格式解”
然后再回头自己的代码
我是把加密后的数据,直接转成了string输出并保存,然后再把这个string进行解密。但是对于这个string,我并没有去指定具体是什么格式的,是utf-8,还是啥,都没有指定。
在大佬的指点下,我把代码进行了修改
整体的逻辑是:
输入要加密的文字内容 + 密钥(密钥的处理直接用示例代码里的即可)
把输出的加密内容,转成hex格式,但是hex格式用户看不了(是乱码),所以hex再转成base64输出,并保存到文件里
解密的时候,先把base64解码后以string格式输出,然后再把这个string转成hex格式以后进行解密
这样一来,加密的时候,实际输出的是hex(只不过为了方便用户看进行了base64编码),输入到解密里的时候,也是hex(从base64转到hex),输入和输出的格式一致,解密成功
加密解密的代码如下:
// 加密消息。 export async function encryptMessagePromise(symKey: string, message: string) { let Key = await genSymKeyByData(new Uint8Array(buffer.from(symKey, 'utf-8').buffer)); let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; let cipher = cryptoFramework.createCipher('SM4_128|ECB|PKCS7'); await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, Key, null); let encryptData = await cipher.doFinal(plainText); let a1 = buffer.from(encryptData.data).toString('hex'); let a2 = buffer.from(a1).toString("base64"); return a2; }
// 解密消息。 export async function decryptMessagePromise(symKey: string, message: string) { let Key = await genSymKeyByData(new Uint8Array(buffer.from(symKey, 'utf-8').buffer)); let base64 = new util.Base64Helper(); let textDecoder: util.TextDecoder = util.TextDecoder.create(); let result: string = textDecoder.decodeToString(base64.decodeSync(message),{stream:true}); let cipherText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(result, 'hex').buffer) }; let decoder = cryptoFramework.createCipher('SM4_128|ECB|PKCS7'); await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, Key, null); let decryptData = await decoder.doFinal(cipherText); let a1 = buffer.from(decryptData.data).toString('utf-8'); return a1; }