Passwd/cloudfunctions/passwd/index.js
Saturneric fb74e7395f Add
2020-09-01 01:19:39 +08:00

500 lines
14 KiB
JavaScript

// 云函数入口文件
const cloud = require('wx-server-sdk')
var crypto = require('crypto');
var CryptoJS = require('crypto-js')
cloud.init({
traceUser: true,
env: "ipasswd-7h7iu"
})
const db = cloud.database()
function encoder(argv) {
var keys = new Array(4);
for (let i = 0; i < 4; i++) {
keys[i] = new Array(10);
}
keys[0] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "#"]
keys[1] = ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "#"]
keys[2] = ["a", "s", "d", "f", "g", "h", "j", "k", "l", "#", "#"]
keys[3] = ["z", "x", "c", "v", "b", "n", "m", "#", "#", "#", "#"]
var rtn = {
data: "",
arrgs: []
}
var pos = new Array(randomer(rtn.arrgs,3), randomer(rtn.arrgs,10))
var vec = new Array(0, 0), nvec = new Array(0, 0)
var getUpper = false, isUpperPoss = 0.2, allGetUpper = false
var getSpecial = false, isSpecialPoss = 0.1, allGetSpecial = false
for (let i = 0; i < argv.length; i++) {
nvec[0] = randomer(rtn.arrgs,50)
nvec[1] = randomer(rtn.arrgs,50)
vec[0] = nvec[0] * 0.08
vec[1] = nvec[1] * 0.24
if (possibility(rtn.arrgs, 0.5)) {
vec[0] *= -1
}
if (possibility(rtn.arrgs, 0.5)) {
vec[1] *= -1
}
pos = new Array(pos[0] + vec[0], pos[1] + vec[1])
if (pos[0] > 3.4 || pos[0] < 0) {
pos[0] = randomer(rtn.arrgs,3)
}
if (pos[1] > 10.4 || pos[1] < 0) {
pos[1] = randomer(rtn.arrgs,10)
}
var tstr = keys[Math.round(pos[0])][Math.round(pos[1])]
if(tstr == "#"){
i -= 1;
continue;
}
if (argv.hasUpper == true){
if (possibility(rtn.arrgs, isUpperPoss)){
tstr = tstr.toUpperCase()
getUpper = true
allGetUpper = true
}
if ((i+2) == argv.length && allGetUpper == false) {
tstr = 'Z';
}
if(getUpper == false){
isUpperPoss *= 1.5
}
else{
getUpper = false
isUpperPoss *= 0.2
if(isUpperPoss < 0.1) isUpperPoss = 0.2
}
}
if (argv.hasSpecial == true) {
if (possibility(rtn.arrgs, isSpecialPoss)) {
var selectedSpecial = argv.specialChar;
var srand = randomer(rtn.arrgs, selectedSpecial.length)
tstr = selectedSpecial[srand]
getSpecial = true
allGetSpecial = true
}
if ((i+1) == argv.length && allGetSpecial == false) {
var selectedSpecial = argv.specialChar;
var srand = randomer(rtn.arrgs, selectedSpecial.length)
tstr = selectedSpecial[srand]
}
if (getSpecial == false) {
isSpecialPoss *= 1.5
}
else {
getSpecial = false
isSpecialPoss *= 0.1
if (isSpecialPoss < 0.05) isSpecialPoss = 0.1
}
}
rtn.data += tstr
}
return rtn
}
function decoder(argv, rands) {
var ridx = 0
var keys = new Array(4);
for (let i = 0; i < 4; i++) {
keys[i] = new Array(10);
}
keys[0] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "#"]
keys[1] = ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "#"]
keys[2] = ["a", "s", "d", "f", "g", "h", "j", "k", "l", "#", "#"]
keys[3] = ["z", "x", "c", "v", "b", "n", "m", "#", "#", "#", "#"]
var rtn = {
data: "",
arrgs: []
}
var pos = new Array(derandomer(rands[ridx++], 3), derandomer(rands[ridx++], 10))
var vec = new Array(0, 0), nvec = new Array(0, 0)
var getUpper = false, isUpperPoss = 0.2, allGetUpper = false
var getSpecial = false, isSpecialPoss = 0.1, allGetSpecial = false
for (let i = 0; i < argv.length; i++) {
nvec[0] = derandomer(rands[ridx++], 50)
nvec[1] = derandomer(rands[ridx++], 50)
vec[0] = nvec[0] * 0.08
vec[1] = nvec[1] * 0.24
if (depossibility(rands[ridx++], 0.5)) {
vec[0] *= -1
}
if (depossibility(rands[ridx++], 0.5)) {
vec[1] *= -1
}
pos = new Array(pos[0] + vec[0], pos[1] + vec[1])
if (pos[0] > 3.4 || pos[0] < 0) {
pos[0] = derandomer(rands[ridx++], 3)
}
if (pos[1] > 10.4 || pos[1] < 0) {
pos[1] = derandomer(rands[ridx++], 10)
}
var tstr = keys[Math.round(pos[0])][Math.round(pos[1])]
if (tstr == "#") {
i -= 1;
continue;
}
if (argv.hasUpper == true) {
if (depossibility(rands[ridx++], isUpperPoss)) {
tstr = tstr.toUpperCase()
getUpper = true
allGetUpper = true
}
if ((i+2) == argv.length && allGetUpper == false) {
tstr = 'Z';
}
if (getUpper == false) {
isUpperPoss *= 1.5
}
else {
getUpper = false
isUpperPoss *= 0.2
if (isUpperPoss < 0.1) isUpperPoss = 0.2
}
}
if (argv.hasSpecial == true) {
if (depossibility(rands[ridx++], isSpecialPoss)) {
var selectedSpecial = argv.specialChar;
var srand = derandomer(rands[ridx++], selectedSpecial.length)
tstr = selectedSpecial[srand]
getSpecial = true
allGetSpecial = true
}
if ((i+1) == argv.length && allGetSpecial == false) {
var selectedSpecial = argv.specialChar;
var srand = derandomer(rands[ridx++], selectedSpecial.length)
tstr = selectedSpecial[srand]
}
if (getSpecial == false) {
isSpecialPoss *= 1.5
}
else {
getSpecial = false
isSpecialPoss *= 0.1
if (isSpecialPoss < 0.05) isSpecialPoss = 0.1
}
}
rtn.data += tstr
}
return rtn
}
function possibility(args, possb){
var tmp = Math.random()
args.push(tmp)
if (possb > tmp){
return true;
}
else return false;
}
function depossibility(arg, possb) {
var tmp = arg
if (possb > tmp) {
return true;
}
else return false;
}
function randomer(args, range) {
var tmp = Math.random()
args.push(tmp)
return Math.floor(tmp * range);
}
function derandomer(arg, range) {
var tmp = arg
return Math.floor(tmp * range);
}
function aes_encrypt(data, openid, iv){
var blocks = parseInt(data.length / 16)
if (data.length % 16 != 0) blocks += 1;
buffdata = new Buffer(16 * blocks)
console.log("Blocks",blocks)
buffdata.write(data)
data = buffdata
console.log("Buffdata",buffdata)
var algorithm = 'aes-256-ecb'
var key = crypto.createHash('sha256').update(openid).digest('hex')
key = key.substr(0, 32)
key = key.toString('hex')
console.log("Data", data, "Key", key)
var clearEncoding = 'ascii'
var cipherEncoding = 'base64'
iv = iv || ""
var cipher = crypto.createCipher(algorithm, key, iv)
cipher.setAutoPadding(true);
var cipherChunks = []
cipherChunks.push(cipher.update(data, clearEncoding, cipherEncoding));
cipherChunks.push(cipher.final(cipherEncoding));
return cipherChunks.join('')
}
function aes_decode(ciphertext, openid, iv){
var algorithm = 'aes-256-ecb'
var key = crypto.createHash('sha256').update(openid).digest('hex')
key = key.substr(0, 32)
key = key.toString('hex')
console.log("Key", key)
var clearEncoding = 'ascii'
var cipherEncoding = 'base64'
iv = iv || "";
var decipher = crypto.createDecipheriv(algorithm, key, iv)
decipher.setAutoPadding(false);
console.log("crypted:" + ciphertext)
var cipherChunks = [];
cipherChunks.push(decipher.update(ciphertext, cipherEncoding, clearEncoding));
cipherChunks.push(decipher.final(clearEncoding));
var decrypted = cipherChunks.join('')
return decrypted;
}
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
console.log("[云函数] 调用 " + event.method)
if (event.method == "encoder") {
var rtn = encoder(event.argv)
var code = String(wxContext.openid)
for (var i = 0; i < rtn.arrgs.length; i++) {
code += String(rtn.arrgs[i])
}
var handle_hash = crypto.createHash('sha256').update(code).digest('hex');
return new Promise((resolve, reject) => {
db.collection('passwd').add({
data: {
openid: wxContext.OPENID,
args: rtn.arrgs,
handle_hash: handle_hash,
argv: event.argv
}
}).then(res => {
if (res.errMsg == "collection.add:ok") {
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
passwd: rtn.data,
handle: handle_hash,
status: "ok"
})
}
else {
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
status: "fail"
})
}
})
})
}
else if (event.method == "saver") {
var handle = event.argv.handle
var openid = event.argv.openid
var tag = event.argv.tag
return new Promise((resolve, reject) => {
db.collection("passwd").where({
handle_hash: handle,
openid: openid
}).limit(1).get().then(res => {
console.log(res)
if (res.data.length > 0) {
var tag_hash = crypto.createHash('sha256').update(tag).digest('hex')
db.collection('passwd_saved').add({
data: {
openid: wxContext.OPENID,
args: res.data[0].args,
handle_hash: handle,
tag_hash: tag_hash,
argv : res.data[0].argv,
custom: false
}
}).then(res => {
if (res.errMsg == "collection.add:ok") {
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
handle: handle_hash,
status: "ok"
})
}
else {
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
status: "fail"
})
}
})
}
})
})
}
else if (event.method == "customer") {
var handle_hash = event.argv.handle
var openid = event.argv.openid
var tag = event.argv.tag
var passwd = event.argv.passwd
return new Promise((resolve, reject) => {
db.collection("passwd").where({
handle_hash: handle_hash,
openid: openid
}).limit(1).get().then(res => {
if (res.data.length > 0) {
var tag_hash = crypto.createHash('sha256').update(tag).digest('hex')
var key = crypto.createHash('sha256').update(openid).digest('hex')
key = key.substr(0, 32)
key = key.toString('hex')
var encrypt = CryptoJS.AES.encrypt(passwd, CryptoJS.enc.Utf8.parse(key), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
db.collection("passwd_saved").add({
data: {
openid: wxContext.OPENID,
ciphertext: encrypt.toString(),
handle_hash: handle_hash,
tag_hash: tag_hash,
custom: true
}
}).then(res => {
if (res.errMsg == "collection.add:ok") {
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
handle: handle_hash,
status: "ok"
})
}
else {
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
status: "fail"
})
}
})
}
})
})
}
else if (event.method == "decoder") {
var handle_hash = event.argv.handle
var openid = event.argv.openid
return new Promise((resolve, reject) => {
db.collection("passwd_saved").where({
handle_hash: handle_hash,
openid: openid
}).limit(1).get().then(res => {
console.log(res)
if (res.data.length > 0) {
if(res.data[0].custom){
var key = crypto.createHash('sha256').update(openid).digest('hex')
key = key.substr(0, 32)
key = key.toString('hex')
var decrypt = CryptoJS.AES.decrypt(res.data[0].ciphertext, CryptoJS.enc.Utf8.parse(key), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
resolve({
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
passwd: decrypt.toString(CryptoJS.enc.Utf8),
status : "ok",
handle : handle_hash
})
}
else{
var args = res.data[0].args
var argv = res.data[0].argv
var rtn = decoder(argv,args)
resolve({
openid: wxContext.OPENID,
appid: wxContext.APPID,
passwd: rtn.data,
status: "ok",
handle: handle_hash
})
}
}
})
})
}
else if (event.method == "deleter"){
var handle_hash = event.argv.handle
var openid = event.argv.openid
return new Promise((resolve, reject) => {
if (wxContext.OPENID != openid){
resolve({
status: "failed",
openid : openid
})
}
var handle = handle_hash
var openid = openid
db.collection("passwd-saved").where({
handle: handle,
openid: wxContext.OPENID
}).get().then(res=>{
console.log(res)
if(res.data.length > 0){
db.collection("passwd-saved").doc(res.data[0]._id).remove().then(res => {
})
resolve({
status: "ok",
openid: openid
})
}
else{
resolve({
status: "failed",
openid: openid
})
}
})
})
}
}