tic-crypto-uniapp/pages/index/index.vue
2022-08-19 21:00:19 +08:00

247 lines
8.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="content">
<button @click="randomBytes" style="background:#Fc4e2b">crypto.randomBytes (微信小程序失败)</button>
<button @click="scrypt" style="background:#Fc4e2b">crypto.scryptSync (全部失败)</button>
<!-- <button @click="secureRandom">secure-random库生成随机字节</button> -->
<button @click="generateMnemonic" style="background:#Fc4e2b">bip39 生成助记词 (微信小程序失败)</button>
<!-- <button @click="test4">bitcore-mnemonic库生成助记词</button>
-->
<button @click="mnemonic2seed" style="background:#Fc4e2b">bip39 从助记词到种子(安卓失败)</button>
<button @click="validateMnemonic" style="background:#Fc4e2b">bip39 验证助记词安卓失败</button>
<button @click="prikey2pubkey" style="background:#Fc4e2b">crypto 私钥转公钥安卓ios微信失败</button>
<view style="display:flex; flex-flow:row; width:100%;">
<button @click="encrypt">crypto对称加密</button>
<button @click="decrypt">crypto对称解密</button>
</view>
<view style="display:flex; flex-flow:row; width:100%;">
<button @click="sign">crypto不对称签名</button>
<button @click="verify">crypto不对称验签</button>
</view>
<view style="display:flex; flex-flow:row; width:100%;">
<button @click="encryptECC">ECC不对称加密</button>
<button @click="decryptECC">ECC不对称解密</button>
</view>
<view style="display:flex; flex-flow:row; width:100%;">
<button @click="signECC">ECC不对称签名</button>
<button @click="verifyECC">ECC不对称验签</button>
</view>
<view class="text-area">
<text class="title">{{ JSON.stringify(title) }}</text>
</view>
</view>
</template>
<script>
import crypto from 'crypto';
import ticc from 'tic-crypto';
import secureRandom from 'secure-random';
import secp256k1 from 'secp256k1';
import hdkey from 'hdkey';
import * as bip39 from 'bip39';
//import * as eccrypto from 'eccrypto-js'; // 签名在浏览器/苹果里都成功。加解密都失败。
import eccrypto from 'eccrypto'; // 签名在浏览器/苹果里都成功。encrypt/decrypt在苹果手机里成功在浏览器里 失败
import keyman from 'js-crypto-key-utils';
const keypair = { prikey: '872d58c1f872636cf2ca460e85f27eb98f4a1fd5f5b70ea702a52c9bf28252ae', pubkey: '03883e6c412431729c78236f7fd6e663c92a863414d7047535b3b386a6410bf331' };
const mnemonic = '滴 民 延 腹 召 罩 巧 舟 小 顶 辩 资';
const signature = '304502210088251984a09c72a887dd8337baee3f65b580ee4e78439fc88935775719cefc670220547dc87e5288edb27990b17f535f10642704e596ce0e50f0a2252cf58dfee275';
const algorithm = 'aes-192-cbc'; // cipher 和 key 的长度必须相同,例如 cipher 是 aes-192那么 key 就必须是 192/8=24 字节 = 48 hex 的。
const key = Buffer.from('8c0ca36264f29389e87d983b269709a92c3455178b271ae0', 'hex')
let cipherECC = {}
let signature2 = ''
export default {
data() {
return {
title: 'uni-app 加密工具兼容性测试。红色按钮的还有问题'hex_to_buf
};
},
onLoad() { },
methods: {
randomBytes() {
try {
this.title = crypto.randomBytes(16).toString('hex');
} catch (exception) {
this.title = exception.toString();
}
},
scrypt() {
try {
this.title = crypto.scryptSync('用户定义的密码', '盐值', 24);
} catch (exception) {
this.title = exception.toString();
}
},
secureRandom() {
try {
this.title = secureRandom(16).toString();
} catch (exception) {
this.title = exception.toString();
}
},
generateMnemonic() {
try {
this.title = bip39.generateMnemonic();
} catch (exception) {
this.title = exception.toString();
}
},
mnemonic2seed() {
try {
bip39.setDefaultWordlist('chinese_simplified');
this.title = bip39.mnemonicToSeedSync('滴 民 延 腹 召 罩 巧 舟 小 顶 辩 资').toString('hex'); // 安卓和ios的微信浏览器iOS app通过安卓app失败
} catch (exception) {
this.title = exception.toString();
}
},
prikey2pubkey() {
try {
this.title = new crypto.createECDH('secp256k1').setPrivateKey(keypair.prikey, 'hex').getPublicKey('hex', 'compressed'); // 在ios和安卓 app里 setPrivateKey() 仍然报错: TypeError: null is not an object (evaluating 'this.rand.getBytes'),微信浏览器里倒成功了
// 另一种算法this.title = secp256k1.publicKeyCreate(Buffer.from(keypair.prikey, 'hex'), true) // 全部通过
} catch (exception) {
this.title = exception.toString();
}
},
validateMnemonic() {
// iOS app 通过,安卓 app 失败,安卓版微信浏览器失败
try {
bip39.setDefaultWordlist('chinese_simplified');
this.title = '正确结果是 true实际结果是' + bip39.validateMnemonic('滴 民 延 腹 召 罩 巧 舟 小 顶 辩 资');
} catch (exception) {
this.title = exception.toString();
}
},
encrypt() {
try {
const iv = Buffer.alloc(16, 0); // 初始化向量。
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('月落乌啼霜满天', 'utf8', 'hex');
encrypted += cipher.final('hex');
this.title = encrypted;
} catch (exception) {
this.title = exception.toString();
}
},
decrypt() {
try {
const iv = Buffer.alloc(16, 0); // 初始化向量。
const decipher = crypto.createDecipheriv(algorithm, key, iv);
// 使用相同的算法、密钥和 iv 进行加密。
const encrypted = "9ac679a1e7d9704df26e345fa91a8dc6feb3faa44fbf1821262a7d5910b76464";
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
this.title = decrypted;
} catch (exception) {
this.title = exception.toString();
}
},
async sign() {
try {
this.title = await ticc.sign({ data: '月落乌啼霜满天', prikey: keypair.prikey })
signature2 = this.title
} catch (exception) {
this.title = exception.toString();
}
},
async verify() {
try {
this.title = await ticc.verify({ data: '月落乌啼霜满天', signature: signature2.toUpperCase(), pubkey: keypair.pubkey }) // 大小写不影响验签!
} catch (exception) {
this.title = exception.toString();
}
},
typedArray2Buffer(array) {
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset);
},
async encryptECC() {
try {
// let kp=eccrypto.generateKeyPair();
var privateKey = eccrypto.generatePrivate();
var publicKey = eccrypto.getPublic(privateKey);
let kp = { privateKey, publicKey }
console.log(kp)
let encrypted = await eccrypto.encrypt(Buffer.from(ticc.hex_to_buf(keypair.pubkey)), '月落乌啼霜满天')
cipherECC = encrypted
this.title = encrypted;
} catch (exception) {
this.title = exception.toString();
}
},
async decryptECC() {
try {
let plaindata = await eccrypto.decrypt(Buffer.from(keypair.prikey, 'hex'), cipherECC)
this.title = plaindata.toString()
} catch (exception) {
this.title = exception.toString();
}
},
async signECC() {
try {
let hashBuf = crypto
.createHash('sha256')
.update('月落乌啼霜满天')
.digest();
this.title = (await eccrypto.sign(Buffer.from(keypair.prikey, 'hex'), hashBuf)).toString('hex');
} catch (exception) {
this.title = exception.toString();
}
},
async verifyECC() {
try {
let hashBuf = crypto
.createHash('sha256')
.update('月落乌啼霜满天')
.digest();
if (null === (await eccrypto.verify(Buffer.from(keypair.pubkey, 'hex'), hashBuf, Buffer.from(signature, 'hex')))) {
this.title = true;
}
} catch (exception) {
this.title = exception.toString();
}
}
}
};
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
flex-flow: column;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
word-break: break-all;
}
button {
margin: 10rpx auto;
}
</style>