|
| 1 | +// SCRAM-SHA-256 (RFC 5802 / 7677) untuk autentikasi PostgreSQL. |
| 2 | +// Memakai builtin kripto: pbkdf2, hmacSha256Raw, sha256Raw, xor, base64, dariBase64, acak. |
| 3 | + |
| 4 | +biar pg_nonce: teks = ""; |
| 5 | +biar pg_cfirst_bare: teks = ""; |
| 6 | + |
| 7 | +// ClientProof (base64) dari sandi, salt mentah, iterasi, dan AuthMessage. |
| 8 | +fungsi pg_scram_proof(sandi: teks, salt: teks, iter: bulat, authMessage: teks): teks { |
| 9 | + biar sp: teks = pbkdf2(sandi, salt, iter); // SaltedPassword |
| 10 | + biar ck: teks = hmacSha256Raw(sp, "Client Key"); // ClientKey |
| 11 | + biar sk: teks = sha256Raw(ck); // StoredKey |
| 12 | + biar cs: teks = hmacSha256Raw(sk, authMessage); // ClientSignature |
| 13 | + kembali base64(xor(ck, cs)); // ClientProof |
| 14 | +} |
| 15 | + |
| 16 | +// Langkah 1: kirim SASLInitialResponse (client-first). |
| 17 | +fungsi pg_scram_mulai(s: bulat): kosong { |
| 18 | + pg_nonce = acak(18); |
| 19 | + pg_cfirst_bare = "n=,r=" + pg_nonce; |
| 20 | + biar cfirst: teks = "n,," + pg_cfirst_bare; |
| 21 | + biar nul: teks = keByte(0, 1, salah); |
| 22 | + biar body: teks = "SCRAM-SHA-256" + nul + keByte(panjangTeks(cfirst), 4, benar) + cfirst; |
| 23 | + kirim(s, pg_pesan(112, body)); // 'p' |
| 24 | +} |
| 25 | + |
| 26 | +// Langkah 2: terima server-first, hitung proof, kirim client-final. |
| 27 | +fungsi pg_scram_lanjut(s: bulat, sandi: teks, serverFirst: teks): kosong { |
| 28 | + biar bagian: []teks = pisah(serverFirst, ","); |
| 29 | + biar rnonce: teks = ""; |
| 30 | + biar saltB64: teks = ""; |
| 31 | + biar iter: bulat = 4096; |
| 32 | + untuk i dari 0 sampai panjang(bagian) { |
| 33 | + biar f: teks = bagian[i]; |
| 34 | + kalau mulaiDengan(f, "r=") { rnonce = potong(f, 2, panjangTeks(f) - 2); } |
| 35 | + kalau mulaiDengan(f, "s=") { saltB64 = potong(f, 2, panjangTeks(f) - 2); } |
| 36 | + kalau mulaiDengan(f, "i=") { iter = keBulat(potong(f, 2, panjangTeks(f) - 2)); } |
| 37 | + } |
| 38 | + biar salt: teks = dariBase64(saltB64); |
| 39 | + biar cfinal_np: teks = "c=biws,r=" + rnonce; |
| 40 | + biar authMessage: teks = pg_cfirst_bare + "," + serverFirst + "," + cfinal_np; |
| 41 | + biar proof: teks = pg_scram_proof(sandi, salt, iter, authMessage); |
| 42 | + kirim(s, pg_pesan(112, cfinal_np + ",p=" + proof)); // 'p' |
| 43 | +} |
0 commit comments