实现数据加密传输,成功调试登录接口

This commit is contained in:
2026-06-07 17:01:41 +08:00
parent aebd264d91
commit 895363305e
9 changed files with 596 additions and 56 deletions
+522
View File
@@ -0,0 +1,522 @@
<template>
<!-- #ifdef APP -->
<scroll-view class="crypto-scroll">
<!-- #endif -->
<view class="crypto-page">
<view class="hero-panel">
<text class="hero-kicker">LAOQIANJUNZI-CRYPTO</text>
<text class="hero-title">统一加密能力演示</text>
<text class="hero-desc">这一页直接调用插件导出的新接口,集中演示编码、摘要、HMAC、AES、3DES、RC4、RSA 与字节数组加解密。</text>
</view>
<view class="card-block runtime-card">
<text class="card-title">运行时概览</text>
<view class="status-row">
<text class="status-label">平台</text>
<text class="status-value">{{ runtimeInfo.platformName }}</text>
</view>
<view class="status-row">
<text class="status-label">引擎</text>
<text class="status-value">{{ runtimeInfo.engineName }}</text>
</view>
<view class="status-row">
<text class="status-label">高级模式</text>
<text class="status-value">{{ runtimeInfo.supportsAdvancedModes ? '已启用' : '受限' }}</text>
</view>
<view class="status-row">
<text class="status-label">原生桥接</text>
<text class="status-value">{{ runtimeInfo.usesNativeBridge ? '是' : '否' }}</text>
</view>
</view>
<view class="card-block form-card">
<text class="card-title">输入参数</text>
<view class="field-group">
<text class="field-label">明文</text>
<input class="field-input" v-model="plainText" />
</view>
<view class="field-group">
<text class="field-label">主密钥</text>
<input class="field-input" v-model="secretText" />
</view>
<view class="field-group">
<text class="field-label">向量</text>
<input class="field-input" v-model="ivText" />
</view>
<view class="field-group">
<text class="field-label">HMAC 密钥</text>
<input class="field-input" v-model="macSecretText" />
</view>
<view class="field-group">
<text class="field-label">3DES 密钥</text>
<input class="field-input" v-model="legacySecretText" />
</view>
<view class="field-group">
<text class="field-label">RSA 位数</text>
<input class="field-input" type="number" v-model="rsaBitsText" />
</view>
</view>
<view class="action-grid">
<button class="action-button action-strong" @click="runAllDemos">运行全部示例</button>
<button class="action-button" @click="runCodecDemo">编码</button>
<button class="action-button" @click="runDigestDemo">摘要/HMAC</button>
<button class="action-button" @click="runAesDemo">AES 文本</button>
<button class="action-button" @click="runByteDemo">AES 字节</button>
<button class="action-button" @click="runLegacyDemo">3DES/RC4</button>
<button class="action-button" @click="runRsaDemo">RSA</button>
<button class="action-button" @click="runCompatDemo">兼容 API</button>
<button class="action-button action-warn" @click="clearResults">清空结果</button>
</view>
<view class="result-grid">
<view class="card-block result-card">
<text class="card-title">编码</text>
<text class="result-line">Base64: {{ codecBase64 }}</text>
<text class="result-line">Hex: {{ codecHex }}</text>
<text class="result-line">Base64url: {{ codecBase64url }}</text>
<text class="result-line">反解: {{ codecBackText }}</text>
</view>
<view class="card-block result-card">
<text class="card-title">摘要与签名</text>
<text class="result-line">MD5: {{ md5Text }}</text>
<text class="result-line">SHA256: {{ sha256Text }}</text>
<text class="result-line">SHA512: {{ sha512Text }}</text>
<text class="result-line">HMAC-SHA256: {{ hmacText }}</text>
</view>
<view class="card-block result-card">
<text class="card-title">AES 文本</text>
<text class="result-line">密文: {{ aesCipherText }}</text>
<text class="result-line">解密: {{ aesPlainText }}</text>
</view>
<view class="card-block result-card">
<text class="card-title">AES 字节</text>
<text class="result-line">字节密文: {{ aesByteCipherHex }}</text>
<text class="result-line">字节解密: {{ aesBytePlainText }}</text>
</view>
<view class="card-block result-card">
<text class="card-title">3DES 与 RC4</text>
<text class="result-line">3DES 密文: {{ tripleCipherText }}</text>
<text class="result-line">3DES 解密: {{ triplePlainText }}</text>
<text class="result-line">RC4 密文: {{ rc4CipherHex }}</text>
<text class="result-line">RC4 解密: {{ rc4PlainText }}</text>
</view>
<view class="card-block result-card">
<text class="card-title">RSA</text>
<text class="result-line">公钥长度: {{ rsaPublicBrief }}</text>
<text class="result-line">私钥长度: {{ rsaPrivateBrief }}</text>
<text class="result-line">RSA 密文: {{ rsaCipherText }}</text>
<text class="result-line">RSA 解密: {{ rsaPlainText }}</text>
</view>
</view>
<view class="card-block log-card">
<text class="card-title">执行日志</text>
<view class="log-list">
<text class="log-line" v-for="(item,index) in logLines" :key="index">{{ item }}</text>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script setup lang="uts">
import { aesDecrypt, aesDecryptBytes, aesDecryptText, aesEncrypt, aesEncryptBytes, aesEncryptText, base64Decode, base64Encode, createRsaPair, defaultByteCipherOptions, defaultTextCipherOptions, defaultTripleDesOptions, decodeText, describeCryptoRuntime, digestText, encodeText, generateRSAKeyPair, md5, rc4DecryptText, rc4EncryptText, rsaDecrypt, rsaDecryptText, rsaEncrypt, rsaEncryptText, signText, tripleDesDecryptText, tripleDesEncryptText, useCrypto } from '@/uni_modules/laoqianjunzi-crypto'
import type { CryptoRuntimeSnapshot } from '@/uni_modules/laoqianjunzi-crypto'
const runtimeInfo = ref(describeCryptoRuntime() as CryptoRuntimeSnapshot)
const plainText = ref('Hello laoqianjunzi-crypto')
const secretText = ref('1234567890abcdef')
const ivText = ref('fedcba0987654321')
const macSecretText = ref('signing-key')
const legacySecretText = ref('1234567890abcdef12345678')
const rsaBitsText = ref('2048')
const codecBase64 = ref('')
const codecHex = ref('')
const codecBase64url = ref('')
const codecBackText = ref('')
const md5Text = ref('')
const sha256Text = ref('')
const sha512Text = ref('')
const hmacText = ref('')
const aesCipherText = ref('')
const aesPlainText = ref('')
const aesByteCipherHex = ref('')
const aesBytePlainText = ref('')
const tripleCipherText = ref('')
const triplePlainText = ref('')
const rc4CipherHex = ref('')
const rc4PlainText = ref('')
const rsaCipherText = ref('')
const rsaPlainText = ref('')
const rsaPublicBrief = ref('')
const rsaPrivateBrief = ref('')
const logLines = ref(['等待执行示例'] as string[])
function appendLog(message : string) : void {
const stamp = new Date().toISOString()
logLines.value.unshift(stamp + ' ' + message)
if (logLines.value.length > 20) {
logLines.value.splice(20)
}
}
function bytesToHex(input : Uint8Array) : string {
let output = ''
let index = 0
while (index < input.length) {
let part = input[index].toString(16)
if (part.length < 2) {
part = '0' + part
}
output += part
index += 1
}
return output
}
function textToBytes(input : string) : Uint8Array {
const output = new Uint8Array(input.length)
let index = 0
while (index < input.length) {
const code = input.charCodeAt(index)
output[index] = code == null ? 0 : code & 0xff
index += 1
}
return output
}
function bytesToText(input : Uint8Array) : string {
let output = ''
let index = 0
while (index < input.length) {
output += String.fromCharCode(input[index])
index += 1
}
return output
}
function currentRsaBits() : number {
const parsed = parseInt(rsaBitsText.value)
if (parsed == 1024 || parsed == 2048 || parsed == 3072 || parsed == 4096) {
return parsed
}
return 2048
}
function runCodecDemo() : void {
codecBase64.value = encodeText('base64', plainText.value)
codecHex.value = encodeText('hex', plainText.value)
codecBase64url.value = encodeText('base64url', plainText.value)
codecBackText.value = decodeText('base64', codecBase64.value)
appendLog('编码能力已完成')
}
function runDigestDemo() : void {
md5Text.value = digestText('md5', plainText.value)
sha256Text.value = digestText('sha256', plainText.value)
sha512Text.value = digestText('sha512', plainText.value)
hmacText.value = signText('sha256', macSecretText.value, plainText.value)
appendLog('摘要与 HMAC 已完成')
}
function runAesDemo() : void {
const options = defaultTextCipherOptions()
options.mode = 'CBC'
options.padding = 'PKCS7'
options.ivText = ivText.value
options.keyLength = 128
aesCipherText.value = aesEncryptText(secretText.value, plainText.value, options)
aesPlainText.value = aesDecryptText(secretText.value, aesCipherText.value, options)
appendLog('AES 文本加解密已完成')
}
function runByteDemo() : void {
const options = defaultByteCipherOptions()
options.mode = 'CTR'
options.padding = 'PKCS7'
options.keyLength = 128
const secretBytes = textToBytes(secretText.value)
const plainBytes = textToBytes(plainText.value)
const cipherBytes = aesEncryptBytes(secretBytes, plainBytes, options)
const restoreBytes = aesDecryptBytes(secretBytes, cipherBytes, options)
aesByteCipherHex.value = bytesToHex(cipherBytes)
aesBytePlainText.value = bytesToText(restoreBytes)
appendLog('AES 字节加解密已完成')
}
function runLegacyDemo() : void {
const options = defaultTripleDesOptions()
options.mode = 'CBC'
options.ivText = '12345678'
tripleCipherText.value = tripleDesEncryptText(legacySecretText.value, plainText.value, options)
triplePlainText.value = tripleDesDecryptText(legacySecretText.value, tripleCipherText.value, options)
rc4CipherHex.value = rc4EncryptText(macSecretText.value, plainText.value)
rc4PlainText.value = rc4DecryptText(macSecretText.value, rc4CipherHex.value)
appendLog('3DES 与 RC4 已完成')
}
function runRsaDemo() : void {
const pair = createRsaPair(currentRsaBits())
rsaPublicBrief.value = pair.publicKey.length + ' chars'
rsaPrivateBrief.value = pair.privateKey.length + ' chars'
rsaCipherText.value = rsaEncryptText(pair.publicKey, plainText.value, 'base64')
rsaPlainText.value = rsaDecryptText(pair.privateKey, rsaCipherText.value, 'base64')
console.log("ggggggggggggggggg"+pair.publicKey);
console.log("sssssssssssssssss"+pair.publicKey);
appendLog('RSA 生成与加解密已完成')
}
function runCompatDemo() : void {
const xBase64 = base64Encode(plainText.value)
const xPlain = base64Decode(xBase64)
const xMd5 = md5(plainText.value)
const xCipher = aesEncrypt(secretText.value, plainText.value, 'CBC', ivText.value, 16)
const xRestore = aesDecrypt(secretText.value, xCipher, 'CBC', ivText.value, 16)
const xPair = generateRSAKeyPair(currentRsaBits())
const xRsaText = rsaDecrypt(xPair.privateKey, rsaEncrypt(xPair.publicKey, plainText.value))
const crypto = useCrypto()
const limeIv = crypto.enc.Utf8.parse(ivText.value)
const limeCipher = crypto.AES.encrypt(plainText.value, secretText.value, {
iv: limeIv,
mode: crypto.mode.CBC,
padding: crypto.pad.Pkcs7
} as UTSJSONObject)
const limePlain = crypto.AES.decrypt(limeCipher.toString(), secretText.value, {
iv: limeIv,
mode: crypto.mode.CBC,
padding: crypto.pad.Pkcs7
} as UTSJSONObject).toString(crypto.enc.Utf8)
const limeRsa = crypto.RSA
const limePair = limeRsa.generateKeyPair()
limeRsa.setPublicKey(limePair.publicKey)
const limeCipherText = limeRsa.encrypt(plainText.value)
limeRsa.setPrivateKey(limePair.privateKey)
const limeRsaText = limeRsa.decrypt(limeCipherText)
appendLog('兼容 API 已完成:x-base64=' + xPlain.length + ' x-md5=' + xMd5.substring(0, 8) + ' x-aes=' + xRestore.length + ' x-rsa=' + xRsaText.length + ' lime-aes=' + limePlain.length + ' lime-rsa=' + limeRsaText.length)
}
function runAllDemos() : void {
try {
runCodecDemo()
runDigestDemo()
runAesDemo()
runByteDemo()
runLegacyDemo()
runRsaDemo()
runCompatDemo()
appendLog('全部能力演示执行结束')
} catch (error) {
appendLog('执行失败:' + (error as Error).message)
}
}
function clearResults() : void {
codecBase64.value = ''
codecHex.value = ''
codecBase64url.value = ''
codecBackText.value = ''
md5Text.value = ''
sha256Text.value = ''
sha512Text.value = ''
hmacText.value = ''
aesCipherText.value = ''
aesPlainText.value = ''
aesByteCipherHex.value = ''
aesBytePlainText.value = ''
tripleCipherText.value = ''
triplePlainText.value = ''
rc4CipherHex.value = ''
rc4PlainText.value = ''
rsaCipherText.value = ''
rsaPlainText.value = ''
rsaPublicBrief.value = ''
rsaPrivateBrief.value = ''
logLines.value = ['结果已清空'] as string[]
}
onMounted(() => {
appendLog('示例页已就绪,点击按钮即可执行')
})
</script>
<style>
.crypto-scroll {
flex: 1;
}
.crypto-page {
display: flex;
flex-direction: column;
padding: 48rpx;
background-color: #efe8dc;
}
.hero-panel {
display: flex;
flex-direction: column;
padding: 40rpx;
border-radius: 48rpx;
background-color: #11231c;
margin-bottom: 36rpx;
}
.hero-kicker {
color: #f2c169;
font-size: 26rpx;
letter-spacing: 4rpx;
margin-bottom: 12rpx;
}
.hero-title {
color: #fff8ea;
font-size: 56rpx;
font-weight: 700;
margin-bottom: 12rpx;
}
.hero-desc {
color: #c9d6cc;
font-size: 28rpx;
line-height: 40rpx;
}
.card-block {
display: flex;
flex-direction: column;
padding: 36rpx;
border-radius: 40rpx;
background-color: #fffaf1;
margin-bottom: 28rpx;
}
.card-title {
color: #24352e;
font-size: 36rpx;
font-weight: 700;
margin-bottom: 18rpx;
}
.runtime-card {
background-color: #f7f1e3;
}
.status-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-bottom-width: 2rpx;
border-bottom-style: solid;
border-bottom-color: #e7dbc8;
}
.status-label {
color: #6b6d66;
font-size: 26rpx;
}
.status-value {
color: #1c2b25;
font-size: 28rpx;
font-weight: 600;
}
.form-card {
background-color: #fff7ee;
}
.field-group {
display: flex;
flex-direction: column;
margin-bottom: 16rpx;
}
.field-label {
color: #6f6258;
font-size: 26rpx;
}
.field-input {
height: 84rpx;
padding: 0 24rpx;
border-radius: 24rpx;
background-color: #f1e7da;
color: #1d2823;
font-size: 28rpx;
}
.action-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 28rpx;
}
.action-button {
min-width: 208rpx;
border-radius: 999rpx;
background-color: #d8e5db;
color: #20312a;
font-size: 26rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
}
.action-strong {
background-color: #17392d;
color: #fff8ef;
}
.action-warn {
background-color: #ead4b9;
color: #5d3722;
}
.result-grid {
display: flex;
flex-direction: column;
}
.result-card {
background-color: #fffdf8;
}
.result-line {
color: #25322c;
font-size: 26rpx;
line-height: 38rpx;
}
.log-card {
background-color: #15261f;
}
.log-list {
display: flex;
flex-direction: column;
}
.log-line {
color: #d6e7dc;
font-size: 24rpx;
line-height: 36rpx;
margin-bottom: 16rpx;
}
</style>