note

a xor k xor k = a

用一次xor是加密,再用相同的key xor一次就可以解開

很多加密是用很多鑰匙和很多xor 和 xor中間加上位移去做加密

密碼需要保護seed和演算法,現在比較注重保護seed(初始值)

SSS injection、SQL injection 如果資料庫或網站沒有寫好,就很容易被攻擊

fail2ban可以擋掉一些外部攻擊 –> 暴力攻擊

helmet 可以擋掉各式各樣的東西,可以啟用裡面的防護措施,讓安全性提高

整數的因數分解是密碼學裡面很重要的一塊

質數在密碼學很重要 因為RSA的出現(public key, private key)

https://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

mod是%

使擴展歐幾里得算法的等效公式算法

// 參考 -- https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
// gcd(a,b) = ri = a*si+b*ti
// gcd(e,N) =  1 = e*si+N*ti
//             1 = e*si mod N  => si=d 是 e 的 modInverse
export function extEuclid(a: bigint, b: bigint) {
  let [si, s] = [1n, 0n] // let si = 1n, s = 0n // let [si,s] = [1n,0n]
  let [ti, t] = [0n, 1n] // let ti = 0n, t = 1n // let [ti,t] = [0n,1n]
  let [ri, r] = [a, b] // let ri = a, r = b   // let [ri,r] = [a,b]
  if (b === 0n)
    return [1n, 0n, a]
  else {
    while (r != 0n) {
      let q = ri / r
      let rt = r; r = ri - q * rt; ri = rt; // [ri, r] = [r, ri-q*r]
      let st = s; s = si - q * st; si = st; // [si, s] = [s, si-q*s]
      let tt = t; t = ti - q * tt; ti = tt; // [ti, t] = [t, ti-q*t]
    }
  }
  return [si, ti, ri]
}xxxxxxxxxx // gcd(a,b) = ri = si+b*tiexport function extEuclid(a: bigint, b: bigint) {  let [si, s] = [1n, 0n] // let si = 1n, s = 0n // let [si,s] = [1n,0n]  let [ti, t] = [0n, 1n] // let ti = 0n, t = 1n // let [ti,t] = [0n,1n]  let [ri, r] = [a, b] // let ri = a, r = b   // let [ri,r] = [a,b]  if (b === 0n)    return [1n, 0n, a]  else {    while (r != 0n) {      let q = ri / r      let rt = r; r = ri - q * rt; ri = rt; // [ri, r] = [r, ri-q*r]      let st = s; s = si - q * st; si = st; // [si, s] = [s, si-q*s]      let tt = t; t = ti - q * tt; ti = tt; // [ti, t] = [t, ti-q*t]    }  }  return [si, ti, ri]}// 參考 -- https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm// gcd(a,b) = ri = a*si+b*ti// gcd(e,N) =  1 = e*si+N*ti//             1 = e*si mod N  => si=d 是 e 的 modInverseexport function extEuclid(a: bigint, b: bigint) {  let [si, s] = [1n, 0n] // let si = 1n, s = 0n // let [si,s] = [1n,0n]  let [ti, t] = [0n, 1n] // let ti = 0n, t = 1n // let [ti,t] = [0n,1n]  let [ri, r] = [a, b] // let ri = a, r = b   // let [ri,r] = [a,b]  if (b === 0n)    return [1n, 0n, a]  else {    while (r != 0n) {      let q = ri / r      let rt = r; r = ri - q * rt; ri = rt; // [ri, r] = [r, ri-q*r]      let st = s; s = si - q * st; si = st; // [si, s] = [s, si-q*s]      let tt = t; t = ti - q * tt; ti = tt; // [ti, t] = [t, ti-q*t]    }  }  return [si, ti, ri]}

求出 modInverse

n

加解密實作

// const NodeRSA = require('node-rsa');
import RSA from "https://dev.jspm.io/node-rsa"

// const key = new RSA({b: 2048});
const keyPem = await Deno.readTextFile("./private.pem")
const key = new RSA(keyPem);
const plaintext = 'pay John => Mary $100';
console.log('plaintext: ', plaintext);
const encrypted = key.encrypt(plaintext, 'base64');
console.log('encrypted: ', encrypted);
const decrypted = key.decrypt(encrypted, 'utf8');
console.log('decrypted: ', decrypted);

const signature = key.sign(plaintext)

const pubPem = await Deno.readTextFile("./public.pem")
const pubKey = new RSA(pubPem);

console.log('signature=', signature)

// const isVerified = key.verify(plaintext, signature)
const isVerified = pubKey.verify(plaintext, signature)
console.log('isVerified=', isVerified)


const isVerified2 = pubKey.verify(plaintext+'a', signature)
console.log('isVerified2=', isVerified2)

signature[0] = signature[0]+1
const isVerified3 = pubKey.verify(plaintext, signature)
console.log('isVerified3=', isVerified3)
export function genKeyPair() {
  let p = B.randomPrime(keySize), q=B.randomPrime(keySize)
  let N = p*q, r=(p-1n)*(q-1n)
  let e = B.randomPrime(keySize) // e<r
  console.log('e=', e)
  console.log('r=', r)
  let d = B.modInv(e, r) // ed=1 mod r, d 如何找? 找一個 k 使(k*r+1)%e == 0
  // 要用 modInverse 函數,參考 https://github.com/rzcoder/node-rsa/blob/master/src/libs/jsbn.js
  // 該算法又參考了書 -- https://cacr.uwaterloo.ca/hac/about/chap14.pdf 14.4.3 Binary extended gcd algorithm
  // 其中的 14.61 Algorithm Binary extended gcd algorithm
  console.log('e*d mod r=', (e*d)%r)
  return {e,d,N}  // e N 是public key, d N 是private key
}

數學難題 : 黎曼猜想