add key pairs for encryption, as well as better styling for posts page
This commit is contained in:
parent
286fe9d74b
commit
3fe83455a3
@ -12,10 +12,12 @@ CREATE TABLE `users` (
|
||||
`User_LastIP` varchar(45) NOT NULL DEFAULT 'None',
|
||||
`User_Bio` varchar(100) DEFAULT 'wow such empty',
|
||||
`User_Avatar` varchar(100) DEFAULT NULL,
|
||||
`User_PublicKey` varchar(830) DEFAULT NULL,
|
||||
PRIMARY KEY (`User_ID`,`User_Name`),
|
||||
UNIQUE KEY `User_Name_UNIQUE` (`User_Name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
|
||||
CREATE TABLE `posts` (
|
||||
`post_id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`post_user_name` varchar(100) NOT NULL,
|
||||
|
@ -3,7 +3,7 @@ ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
background-color: #303034;
|
||||
}
|
||||
|
||||
li {
|
||||
|
@ -7,7 +7,7 @@
|
||||
}
|
||||
|
||||
.self {
|
||||
color: gray;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#username-self {
|
||||
@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
#posts > div {
|
||||
background-color: darkgray;
|
||||
background-color: #303034;
|
||||
padding-left: 5px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
@ -51,15 +51,15 @@
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: black;
|
||||
background-color: #1B1B1E;
|
||||
}
|
||||
|
||||
textarea {
|
||||
background-color: gray;
|
||||
background-color: #1B1B1E;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: gray;
|
||||
background-color: #587291;
|
||||
}
|
||||
|
||||
* {
|
||||
@ -67,6 +67,7 @@ button {
|
||||
}
|
||||
|
||||
.post,.self,.status {
|
||||
color: #ECEAF1;
|
||||
width: 50%;
|
||||
margin-left: 25%;
|
||||
margin-right: 25%;
|
||||
|
38
js/RSA.js
Normal file
38
js/RSA.js
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
var RSAAPP={};RSAAPP.NoPadding="NoPadding";RSAAPP.PKCS1Padding="PKCS1Padding";RSAAPP.RawEncoding="RawEncoding";RSAAPP.NumericEncoding="NumericEncoding"
|
||||
function RSAKeyPair(encryptionExponent,decryptionExponent,modulus,keylen)
|
||||
{this.e=biFromHex(encryptionExponent);this.d=biFromHex(decryptionExponent);this.m=biFromHex(modulus);if(typeof(keylen)!='number'){this.chunkSize=2*biHighIndex(this.m);}
|
||||
else{this.chunkSize=keylen/8;}
|
||||
this.radix=16;this.barrett=new BarrettMu(this.m);}
|
||||
function encryptedString(key,s,pad,encoding)
|
||||
{var a=new Array();var sl=s.length;var i,j,k;var padtype;var encodingtype;var rpad;var al;var result="";var block;var crypt;var text;if(typeof(pad)=='string'){if(pad==RSAAPP.NoPadding){padtype=1;}
|
||||
else if(pad==RSAAPP.PKCS1Padding){padtype=2;}
|
||||
else{padtype=0;}}
|
||||
else{padtype=0;}
|
||||
if(typeof(encoding)=='string'&&encoding==RSAAPP.RawEncoding){encodingtype=1;}
|
||||
else{encodingtype=0;}
|
||||
if(padtype==1){if(sl>key.chunkSize){sl=key.chunkSize;}}
|
||||
else if(padtype==2){if(sl>(key.chunkSize-11)){sl=key.chunkSize-11;}}
|
||||
i=0;if(padtype==2){j=sl-1;}
|
||||
else{j=key.chunkSize-1;}
|
||||
while(i<sl){if(padtype){a[j]=s.charCodeAt(i);}
|
||||
else{a[i]=s.charCodeAt(i);}
|
||||
i++;j--;}
|
||||
if(padtype==1){i=0;}
|
||||
j=key.chunkSize-(sl%key.chunkSize);while(j>0){if(padtype==2){rpad=Math.floor(Math.random()*256);while(!rpad){rpad=Math.floor(Math.random()*256);}
|
||||
a[i]=rpad;}
|
||||
else{a[i]=0;}
|
||||
i++;j--;}
|
||||
if(padtype==2)
|
||||
{a[sl]=0;a[key.chunkSize-2]=2;a[key.chunkSize-1]=0;}
|
||||
al=a.length;for(i=0;i<al;i+=key.chunkSize){block=new BigInt();j=0;for(k=i;k<(i+key.chunkSize);++j){block.digits[j]=a[k++];block.digits[j]+=a[k++]<<8;}
|
||||
crypt=key.barrett.powMod(block,key.e);if(encodingtype==1){text=biToBytes(crypt);}
|
||||
else{text=(key.radix==16)?biToHex(crypt):biToString(crypt,key.radix);}
|
||||
result+=text;}
|
||||
return result;}
|
||||
function decryptedString(key,c)
|
||||
{var blocks=c.split(" ");var b;var i,j;var bi;var result="";for(i=0;i<blocks.length;++i){if(key.radix==16){bi=biFromHex(blocks[i]);}
|
||||
else{bi=biFromString(blocks[i],key.radix);}
|
||||
b=key.barrett.powMod(bi,key.d);for(j=0;j<=biHighIndex(b);++j){result+=String.fromCharCode(b.digits[j]&255,b.digits[j]>>8);}}
|
||||
if(result.charCodeAt(result.length-1)==0){result=result.substring(0,result.length-1);}
|
||||
return(result);}
|
27
js/user.js
27
js/user.js
@ -31,7 +31,34 @@ function progressHandler(event) {
|
||||
console.log(event.target.responseText);
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function setCookie(cname, cvalue, exdays) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
||||
let expires = "expires="+ d.toUTCString();
|
||||
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
async function setuser() {
|
||||
if(getCookie("priv_key") != "") {
|
||||
localStorage.setItem("priv_key",getCookie("priv_key"))
|
||||
setCookie("priv_key","",0)
|
||||
}
|
||||
let user = await (await fetch("/api/getuser")).json();
|
||||
let username
|
||||
let bio
|
||||
|
71
server.js
71
server.js
@ -339,12 +339,16 @@ router.use("/api/*",async function(req,res,next) {
|
||||
values[1] = SHA256(values[1],values[0],HASHES_DIFF)
|
||||
res.locals.bio = ""
|
||||
res.locals.avatar = ""
|
||||
res.locals.publicKey = ""
|
||||
res.locals.privateKey = ""
|
||||
con.query(sql, values, function (err, result) {
|
||||
if (err) throw err;
|
||||
if(result[0] && result[0].User_Name && result[0].User_Name == values[0]) {
|
||||
res.locals.username = values[0];
|
||||
res.locals.bio = result[0].User_Bio || ""
|
||||
res.locals.avatar = result[0].User_Avatar || ""
|
||||
res.locals.publicKey = result[0].User_PublicKey || ""
|
||||
res.locals.privateKey = result[0].User_PrivateKey || ""
|
||||
next()
|
||||
} else {
|
||||
res.status(400)
|
||||
@ -367,7 +371,7 @@ router.get("/api/search", async function(req,res) {
|
||||
}
|
||||
});
|
||||
}else if (type=="post") {
|
||||
let sql = `select post_user_name,post_text,post_time,post_special_text,post_id from zerotwohub.posts where post_text like ? order by post_id desc limit 20;`
|
||||
let sql = `select post_user_name,post_text,post_time,post_special_text,post_id from zerotwohub.posts where post_text like ? and (post_receiver_name is null or post_receiver_name = 'everyone') order by post_id desc limit 20;`
|
||||
con.query(sql, [`%${arg}%`], function (err, result) {
|
||||
if (err) throw err;
|
||||
if(result[0]) {
|
||||
@ -468,13 +472,16 @@ router.post("/api/post", async function(req,res) {
|
||||
return
|
||||
}
|
||||
req.body.message = encodeURIComponent(req.body.message.trim())
|
||||
req.body.receiver = encodeURIComponent(req.body.receiver||"")
|
||||
if(req.body.receiver == "")req.body.receiver="everyone"
|
||||
|
||||
if(!req.body.message) {
|
||||
res.json({"error":"no message to post"})
|
||||
return
|
||||
}
|
||||
|
||||
let sql = `insert into zerotwohub.posts (post_user_name,post_text,post_time) values (?,?,?);`
|
||||
let values = [encodeURIComponent(res.locals.username),req.body.message,Date.now()]
|
||||
let sql = `insert into zerotwohub.posts (post_user_name,post_text,post_time,post_receiver_name) values (?,?,?,?);`
|
||||
let values = [encodeURIComponent(res.locals.username),req.body.message,Date.now(),req.body.receiver]
|
||||
con.query(sql, values, function (err, result) {
|
||||
if (err) throw err;
|
||||
|
||||
@ -724,16 +731,34 @@ router.post("/register",async function(req,res) {
|
||||
res.redirect("/register?success=false&reason=already_exists")
|
||||
return
|
||||
}
|
||||
let hashed_pw = SHA256(password,username,HASHES_DB)
|
||||
let less_hashed_pw = SHA256(password,username,HASHES_DIFF)
|
||||
let hashed_pw = SHA256(less_hashed_pw,username,HASHES_COOKIE)
|
||||
let ip = req.socket.remoteAddress
|
||||
let setTo = username + " " + SHA256(password,username,HASHES_COOKIE)
|
||||
let cookiesigned = signature.sign(setTo, cookiesecret+ip);
|
||||
ip = SHA256(ip,setTo,HASHES_DB)
|
||||
let values = [encodeURIComponent(username),hashed_pw, Date.now(), ip, ip]
|
||||
let sql = `INSERT INTO zerotwohub.users (User_Name, User_PW, User_CreationStamp, User_CreationIP, User_LastIP) VALUES (?, ?, ?, ? ,?);`
|
||||
const {
|
||||
publicKey,
|
||||
privateKey,
|
||||
} = crypto.generateKeyPairSync('rsa', {
|
||||
modulusLength: 4096,
|
||||
publicKeyEncoding: {
|
||||
type: 'spki',
|
||||
format: 'pem'
|
||||
},
|
||||
privateKeyEncoding: {
|
||||
type: 'pkcs8',
|
||||
format: 'pem',
|
||||
cipher: 'aes-256-cbc',
|
||||
passphrase: password
|
||||
}
|
||||
});
|
||||
let values = [encodeURIComponent(username),hashed_pw, Date.now(), ip, ip, publicKey.toString(), privateKey.toString()]
|
||||
let sql = `INSERT INTO zerotwohub.users (User_Name, User_PW, User_CreationStamp, User_CreationIP, User_LastIP, User_PublicKey, User_PrivateKey) VALUES (?, ?, ?, ?, ?, ?, ?);`
|
||||
con.query(sql, values, function (err, result) {
|
||||
if (err) throw err;
|
||||
res.cookie('AUTH_COOKIE',cookiesigned, { maxAge: Math.pow(10,10), httpOnly: true, secure: DID_I_FINALLY_ADD_HTTPS });
|
||||
res.cookie("priv_key",privateKey.toString(), { maxAge: Math.pow(10,10), httpOnly: false, secure: DID_I_FINALLY_ADD_HTTPS }) //only meant to be used as temporary storage, moved to localStorage on user page
|
||||
res.redirect("/user?success=true")
|
||||
});
|
||||
})
|
||||
@ -784,26 +809,50 @@ router.post("/login",async function(req,res) {
|
||||
res.send("no password given")
|
||||
return
|
||||
}
|
||||
let less_hashed_pw = SHA256(password,username,HASHES_DIFF)
|
||||
let hashed_pw = SHA256(less_hashed_pw,username,HASHES_COOKIE)
|
||||
|
||||
let hashed_pw = SHA256(password,username,HASHES_DB)
|
||||
|
||||
let userexistssql = `SELECT User_Name,User_PW,User_LastIP from zerotwohub.users where User_Name = ? and User_PW = ?;`
|
||||
let userexistssql = `SELECT * from zerotwohub.users where User_Name = ? and User_PW = ?;`
|
||||
con.query(userexistssql,[encodeURIComponent(username),hashed_pw],function(error,result) {
|
||||
if(result && result[0]) {
|
||||
let ip = req.socket.remoteAddress
|
||||
let setTo = username + " " + SHA256(password,username,HASHES_COOKIE)
|
||||
let cookiesigned = signature.sign(setTo, cookiesecret+ip);
|
||||
res.cookie('AUTH_COOKIE',cookiesigned, { maxAge: Math.pow(10,10), httpOnly: true, secure: DID_I_FINALLY_ADD_HTTPS });
|
||||
res.redirect("/user?success=true")
|
||||
|
||||
ip = SHA256(ip,setTo,HASHES_DB)
|
||||
|
||||
if(result[0].User_PublicKey == null) {
|
||||
const {
|
||||
publicKey,
|
||||
privateKey,
|
||||
} = crypto.generateKeyPairSync('rsa', {
|
||||
modulusLength: 4096,
|
||||
publicKeyEncoding: {
|
||||
type: 'spki',
|
||||
format: 'pem'
|
||||
},
|
||||
privateKeyEncoding: {
|
||||
type: 'pkcs8',
|
||||
format: 'pem',
|
||||
cipher: 'aes-256-cbc',
|
||||
passphrase: password
|
||||
}
|
||||
});
|
||||
res.cookie("priv_key",privateKey.toString(), { maxAge: Math.pow(10,10), httpOnly: false, secure: DID_I_FINALLY_ADD_HTTPS }) //only meant to be used as temporary storage, moved to localStorage on user page
|
||||
let sql = `update zerotwohub.users set User_PublicKey=?,User_PrivateKey=? where User_Name = ?;`
|
||||
con.query(sql,[publicKey.toString(),privateKey.toString(),encodeURIComponent(username)],function(error,result) {
|
||||
if(error)throw error
|
||||
})
|
||||
} else {
|
||||
res.cookie("priv_key",result[0].User_PrivateKey, { maxAge: Math.pow(10,10), httpOnly: false, secure: DID_I_FINALLY_ADD_HTTPS }) //only meant to be used as temporary storage, moved to localStorage on user page
|
||||
}
|
||||
if(result[0].User_LastIP != ip) {
|
||||
let sql = `update zerotwohub.users set User_LastIP = ? where User_Name = ?;`
|
||||
con.query(sql,[ip,encodeURIComponent(username)],function(error,result) {
|
||||
if(error)throw error
|
||||
})
|
||||
}
|
||||
res.redirect("/user?success=true")
|
||||
} else {
|
||||
res.redirect("/login?success=false?reason=noUser")
|
||||
}
|
||||
|
@ -4,8 +4,9 @@
|
||||
<link rel="stylesheet" href="/css/logon.css">
|
||||
<script type="text/javascript">
|
||||
function login() {
|
||||
const user = document.getElementById("user").value
|
||||
const pw = document.getElementById("pass").value
|
||||
localStorage.setItem("decryption_key",pw)
|
||||
//yes I know this is not secure, but at this point I think it'd be better to trust the client for end-to-end encryption
|
||||
}
|
||||
</script>
|
||||
<script src="/js/addnavbar.js" charset="utf-8"></script>
|
||||
|
@ -4,8 +4,9 @@
|
||||
<link rel="stylesheet" href="/css/logon.css">
|
||||
<script type="text/javascript">
|
||||
function register() {
|
||||
const user = document.getElementById("user").value
|
||||
const pw = document.getElementById("pass").value
|
||||
localStorage.setItem("decryption_key",pw)
|
||||
//yes I know this is not secure, but at this point I think it'd be better to trust the client for end-to-end encryption
|
||||
}
|
||||
</script>
|
||||
<script src="/js/addnavbar.js" charset="utf-8"></script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user