Last active
May 23, 2021 17:00
-
-
Save sdaves/70384b896e858f7d7abee1678d1b3fda to your computer and use it in GitHub Desktop.
Securely generate passwords for every service you use based on a shared master password.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Cryptopass Web</title> | |
<script> | |
//https://unpkg.com/[email protected]/lib/index.browser.bundle.iife.js | |
var pbkdf2Hmac=function(){"use strict";const e={"SHA-1":{outputLength:20,blockSize:64},"SHA-256":{outputLength:32,blockSize:64},"SHA-384":{outputLength:48,blockSize:128},"SHA-512":{outputLength:64,blockSize:128}};function t(...e){const t=e.reduce((e,t)=>e+t.length,0);if(!e.length)throw new RangeError("Cannot concat no arrays");const r=new Uint8Array(t);let n=0;for(const t of e)r.set(t,n),n+=t.length;return r}function r(e,t){for(let r=0;r<e.length;r++)e[r]^=t[r]}return function(n,a,o,i,s="SHA-256"){return new Promise((c,u)=>{s in e||u(new RangeError("Valid hash algorithm values are any of "+Object.keys(e))),"string"==typeof n?n=(new TextEncoder).encode(n):n instanceof ArrayBuffer?n=new Uint8Array(n):ArrayBuffer.isView(n)||u(RangeError("P should be string, ArrayBuffer, TypedArray, DataView")),"string"==typeof a?a=(new TextEncoder).encode(a):a instanceof ArrayBuffer?a=new Uint8Array(a):ArrayBuffer.isView(a)||u(RangeError("S should be string, ArrayBuffer, TypedArray, DataView")),crypto.subtle.importKey("raw",n,"PBKDF2",!1,["deriveBits"]).then(f=>{const y={name:"PBKDF2",hash:s,salt:a,iterations:o};crypto.subtle.deriveBits(y,f,8*i).then(e=>c(e),f=>{(async function(n,a,o,i,s){if(!(s in e))throw new RangeError("Valid hash algorithm values are any of "+Object.keys(e));if(!Number.isInteger(o)||o<=0)throw new RangeError("c must be a positive integer");const c=e[s].outputLength;if(!Number.isInteger(i)||i<=0||i>=(2**32-1)*c)throw new RangeError("dkLen must be a positive integer < (2 ** 32 - 1) * hLen");const u=Math.ceil(i/c),f=i-(u-1)*c,y=new Array(u);0===n.length&&(n=new Uint8Array(e[s].blockSize));n=await crypto.subtle.importKey("raw",n,{name:"HMAC",hash:{name:s}},!0,["sign"]);const w=async function(e,t){const r=await crypto.subtle.sign("HMAC",e,t);return new Uint8Array(r)};for(let e=0;e<u;e++)y[e]=await h(n,a,o,e+1);async function h(e,n,a,o){const i=await w(e,t(n,function(e){const t=new ArrayBuffer(4);return new DataView(t).setUint32(0,e,!1),new Uint8Array(t)}(o)));let s=i;for(let t=1;t<a;t++)s=await w(e,s),r(i,s);return i}return y[u-1]=y[u-1].slice(0,f),t(...y).buffer})(n,a,o,i,s).then(e=>c(e),e=>u(e))})},e=>u(e))})}}(); | |
</script> | |
<script> | |
//https://cdn.jsdelivr.net/npm/[email protected]/base64.min.js | |
/** | |
* Minified by jsDelivr using Terser v5.3.5. | |
* Original file: /npm/[email protected]/base64.js | |
* | |
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files | |
*/ | |
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):function(){const r=e.Base64,o=t();o.noConflict=()=>(e.Base64=r,o),e.Meteor&&(Base64=o),e.Base64=o}()}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this,(function(){"use strict";const e="3.6.1",t="function"==typeof atob,r="function"==typeof btoa,o="function"==typeof Buffer,n="function"==typeof TextDecoder?new TextDecoder:void 0,a="function"==typeof TextEncoder?new TextEncoder:void 0,f=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="],i=(e=>{let t={};return e.forEach(((e,r)=>t[e]=r)),t})(f),c=/^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/,u=String.fromCharCode.bind(String),s="function"==typeof Uint8Array.from?Uint8Array.from.bind(Uint8Array):(e,t=(e=>e))=>new Uint8Array(Array.prototype.slice.call(e,0).map(t)),d=e=>e.replace(/[+\/]/g,(e=>"+"==e?"-":"_")).replace(/=+$/m,""),l=e=>e.replace(/[^A-Za-z0-9\+\/]/g,""),h=e=>{let t,r,o,n,a="";const i=e.length%3;for(let i=0;i<e.length;){if((r=e.charCodeAt(i++))>255||(o=e.charCodeAt(i++))>255||(n=e.charCodeAt(i++))>255)throw new TypeError("invalid character found");t=r<<16|o<<8|n,a+=f[t>>18&63]+f[t>>12&63]+f[t>>6&63]+f[63&t]}return i?a.slice(0,i-3)+"===".substring(i):a},p=r?e=>btoa(e):o?e=>Buffer.from(e,"binary").toString("base64"):h,y=o?e=>Buffer.from(e).toString("base64"):e=>{let t=[];for(let r=0,o=e.length;r<o;r+=4096)t.push(u.apply(null,e.subarray(r,r+4096)));return p(t.join(""))},A=(e,t=!1)=>t?d(y(e)):y(e),b=e=>{if(e.length<2)return(t=e.charCodeAt(0))<128?e:t<2048?u(192|t>>>6)+u(128|63&t):u(224|t>>>12&15)+u(128|t>>>6&63)+u(128|63&t);var t=65536+1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320);return u(240|t>>>18&7)+u(128|t>>>12&63)+u(128|t>>>6&63)+u(128|63&t)},g=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g,B=e=>e.replace(g,b),x=o?e=>Buffer.from(e,"utf8").toString("base64"):a?e=>y(a.encode(e)):e=>p(B(e)),C=(e,t=!1)=>t?d(x(e)):x(e),m=e=>C(e,!0),U=/[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g,F=e=>{switch(e.length){case 4:var t=((7&e.charCodeAt(0))<<18|(63&e.charCodeAt(1))<<12|(63&e.charCodeAt(2))<<6|63&e.charCodeAt(3))-65536;return u(55296+(t>>>10))+u(56320+(1023&t));case 3:return u((15&e.charCodeAt(0))<<12|(63&e.charCodeAt(1))<<6|63&e.charCodeAt(2));default:return u((31&e.charCodeAt(0))<<6|63&e.charCodeAt(1))}},w=e=>e.replace(U,F),S=e=>{if(e=e.replace(/\s+/g,""),!c.test(e))throw new TypeError("malformed base64.");e+="==".slice(2-(3&e.length));let t,r,o,n="";for(let a=0;a<e.length;)t=i[e.charAt(a++)]<<18|i[e.charAt(a++)]<<12|(r=i[e.charAt(a++)])<<6|(o=i[e.charAt(a++)]),n+=64===r?u(t>>16&255):64===o?u(t>>16&255,t>>8&255):u(t>>16&255,t>>8&255,255&t);return n},E=t?e=>atob(l(e)):o?e=>Buffer.from(e,"base64").toString("binary"):S,v=o?e=>s(Buffer.from(e,"base64")):e=>s(E(e),(e=>e.charCodeAt(0))),D=e=>v(z(e)),R=o?e=>Buffer.from(e,"base64").toString("utf8"):n?e=>n.decode(v(e)):e=>w(E(e)),z=e=>l(e.replace(/[-_]/g,(e=>"-"==e?"+":"/"))),T=e=>R(z(e)),Z=e=>({value:e,enumerable:!1,writable:!0,configurable:!0}),j=function(){const e=(e,t)=>Object.defineProperty(String.prototype,e,Z(t));e("fromBase64",(function(){return T(this)})),e("toBase64",(function(e){return C(this,e)})),e("toBase64URI",(function(){return C(this,!0)})),e("toBase64URL",(function(){return C(this,!0)})),e("toUint8Array",(function(){return D(this)}))},I=function(){const e=(e,t)=>Object.defineProperty(Uint8Array.prototype,e,Z(t));e("toBase64",(function(e){return A(this,e)})),e("toBase64URI",(function(){return A(this,!0)})),e("toBase64URL",(function(){return A(this,!0)}))},O={version:e,VERSION:"3.6.1",atob:E,atobPolyfill:S,btoa:p,btoaPolyfill:h,fromBase64:T,toBase64:C,encode:C,encodeURI:m,encodeURL:m,utob:B,btou:w,decode:T,isValid:e=>{if("string"!=typeof e)return!1;const t=e.replace(/\s+/g,"").replace(/=+$/,"");return!/[^\s0-9a-zA-Z\+/]/.test(t)||!/[^\s0-9a-zA-Z\-_]/.test(t)},fromUint8Array:A,toUint8Array:D,extendString:j,extendUint8Array:I,extendBuiltins:()=>{j(),I()},Base64:{}};return Object.keys(O).forEach((e=>O.Base64[e]=O[e])),O})); | |
</script> | |
</head> | |
<style> | |
body { | |
background-color:black; | |
} | |
#root { | |
color:white; | |
text-align:center; | |
margin-top:20%; | |
} | |
</style> | |
<script> | |
async function generate(secret, user, domain) { | |
const hmac = await pbkdf2Hmac(secret, user + '@' + domain, 5000, 32) | |
const val = Base64.fromUint8Array(new Uint8Array(hmac)) | |
return val.substring(0,25) | |
} | |
async function main() { | |
const val = await generate(prompt("Master Secret Password: \n (Can be the same across accounts, use letters, numbers, symbols, etc.)"), prompt("Site Username: \n (Example: [email protected], whatever123, etc.)"), prompt("Site Domain: \n (Example: google.com, sub.mysite.com, etc.)")) | |
window["root"].innerHTML=val | |
} | |
</script> | |
<body onload="main()"> | |
<div id="root"></div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import os | |
os.system("python -m pip install PySimpleGUI pyperclip pyinstaller shortcut") | |
import sys, shortcut, stat, hashlib as h, base64 as b, PySimpleGUI as sg, pyperclip as p | |
def install(): | |
try: | |
os.mkdir(os.getenv("HOME") + "/.local/share/applications") | |
except: | |
pass | |
name = "simplepassword.py" | |
s = os.stat(name) | |
os.chmod(name, s.st_mode | stat.S_IEXEC) | |
platform = sys.platform | |
if sys.platform.startswith("linux"): | |
platform = "linux" | |
# operating system specific imports | |
if platform == "win32": | |
from shortcut.windows import ShortCutterWindows as ShortCutter | |
elif platform == "linux": | |
from shortcut.linux import ShortCutterLinux as ShortCutter | |
elif platform == "darwin": | |
from shortcut.macos import ShortCutterMacOS as ShortCutter | |
else: | |
raise Exception("Error: '{}' platform is not supported.") | |
shortcutter = ShortCutter() | |
target_path = shortcutter.find_target(name) | |
shortcutter.create_desktop_shortcut(target_path) | |
shortcutter.create_menu_shortcut(target_path) | |
def generate(secret, user, domain): | |
val = lambda x: bytearray(map(ord, x)) | |
hmac = h.pbkdf2_hmac("sha256", val(secret), val(f"{user}@{domain}"), 5000) | |
return b.b64encode(hmac)[:25].decode() | |
def main(): | |
win = sg.Window( | |
"SimplePassword", | |
[ | |
[ | |
sg.Text("Master Secret Password:", justification="right", size=(30, 0)), | |
sg.Input(), | |
], | |
[ | |
sg.Text("Site Username:", size=(30, 0), justification="right"), | |
sg.Input(), | |
], | |
[ | |
sg.Text( | |
"Site Domain (Example: google.com):", | |
justification="right", | |
size=(30, 0), | |
), | |
sg.Input(), | |
], | |
[sg.OK(), sg.Cancel(), sg.Button("Install")], | |
], | |
) | |
event, values = win.read() | |
win.Hide() | |
win.close() | |
if event == "OK": | |
p.copy(generate(values[0], values[1], values[2])) | |
elif event == "Install": | |
install() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment