Creare un segreto
Interrogazione API: POST https://password.link/api/secrets
Tipo di chiave API richiesta: chiave API privata
Un esempio di crittografia di un segreto e di invio all'API di password.link utilizzando JavaScript. Utilizza jQuery, seedrandom e SJCL.
Uno script come questo può essere utilizzato su un computer locale o su una rete locale per creare comodamente i segreti sul nostro servizio, ma non va mai inserito in un luogo pubblico senza un'adeguata autenticazione.
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<!-- Get the latest jQuery from https://jquery.com -->
<script src="jquery-3.4.1.min.js"></script>
<!-- Get sjcl.js from https://github.com/bitwiseshiftleft/sjcl -->
<script src="sjcl.js"></script>
<!-- Get seedrandom.min.js from https://github.com/davidbau/seedrandom -->
<script src="seedrandom.min.js"></script>
<script>
// Set the base URL for the generated link
var LINK_BASE_URL = "https://some.site/secret.html";
// Set the API key here - a private API key is required
var PRIVATE_API_KEY = "private_key_abcd...";
// ----------------------------------- //
// A function for sending the secret to password.link API
function send_to_passwordlink_api(secret) {
// Create the public password part
var password_part_public = generate_string();
var password_part_public_base64 = btoa(password_part_public);
// Create the private password part
var password_part_private = generate_string();
var password_part_private_base64 = btoa(password_part_private);
// Create an SJCL compatible Base64 encoded ciphertext
var ciphertext = encrypt_secret(password_part_public, password_part_private, secret);
// The data which will be sent over to the password.link API
var data = {
"ciphertext": ciphertext,
"password_part_private": password_part_private_base64
};
// Send a request to the password.link API and process the result
$.ajax({
type: "POST",
url: "https://password.link/api/secrets",
dataType: "json",
contentType: "application/json",
headers: {
"Authorization": "ApiKey " + PRIVATE_API_KEY
},
data: JSON.stringify(data),
success: function(data) {
var secret = data.data;
var meta = data.metadata;
var secret_url = LINK_BASE_URL + "?" + secret.id + "#" + password_part_public_base64;
$("#secret").html("URL to secret: " + secret_url);
$("#secret-meta").html("Total secrets: " + meta.secrets_total);
$("#secret-meta").append("<br> Usage: " + meta.secrets_usage);
$("#secret-meta").append("<br> Allowance: " + meta.secrets_allowance);
},
error: function(data) {
var error = data.responseJSON.error;
$("#secret").html("Error: " + error.message);
}
});
}
// A function for encrypting a secret, returns a Base64 encoded SJCL compatible ciphertext
function encrypt_secret(password_part_public, password_part_private, secret) {
try {
var ciphertext_base64 = btoa(sjcl.encrypt(
password_part_private + password_part_public,
secret,
{ "mode": "gcm", "ks": 256, "iter": 10000 }
));
return ciphertext_base64;
}
// Catch and show errors
catch(e) {
$("#secret").html("Error during encryption: " + e);
}
}
// A function for generating a random 18 characters long string
function generate_string() {
var len = 18;
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$|/\!_+,.-?()[]{}<>&#^*=@";
// Use seedrandom.js to create autoseeded PRNG
Math.seedrandom();
var str = "";
for (var i = 0; i < len; i++) {
str += chars.charAt(Math.floor(Math.random() * chars.length));
}
return str;
}
// Execute the send function when the button is clicked
$(document).ready(function() {
$("#secret-button").click(function(e) {
e.preventDefault();
var secret = $("#secret-input").val();
send_to_passwordlink_api(secret);
});
});
</script>
<style>
body {
font: 12px Arial;
}
.container {
max-width: 960px;
margin: 0 auto;
text-align: center;
margin-top: 60px;
}
#secret {
margin-top: 30px;
font-size: 18px;
}
#secret-meta {
margin-top: 40px;
}
.secret-form {
display: flex;
flex-flow: row wrap;
align-items: center;
flex-direction: vertical;
justify-content: center;
}
.secret-form input {
vertical-align: middle;
margin: 5px 10px 5px 0;
padding: 10px;
border: 1px solid #ddd;
width: 200px;
}
.secret-form button {
padding: 10px 20px;
border: 1px solid #ddd;
}
.secret-form button:hover {
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h2>Encrypt and create a secret on password.link</h2>
<form class="secret-form">
<input id="secret-input" type="text" name="secret">
<button id="secret-button">Encrypt and create link</button>
</form>
<!-- This div will contain the link to the secret (or error) -->
<div id="secret"></div>
<div id="secret-meta"></div>
</div>
</body>
</html>
Visualizza il segreto
Interrogazione API: GET https://password.link/api/secrets/<id>
Tipo di chiave API richiesta: chiave API pubblica
Un esempio di acquisizione, decodifica e visualizzazione di un segreto tramite JavaScript. Utilizza jQuery e SJCL.
Uno script come questo può essere usato per creare una pagina segreta di visualizzazione autogestita.
<html>
<head>
<!-- Get the latest jQuery from https://jquery.com -->
<script src="jquery-3.4.1.min.js"></script>
<!-- Get sjcl.js from https://github.com/bitwiseshiftleft/sjcl -->
<script src="sjcl.js"></script>
<style>
body {
font: 12px Arial;
}
.container {
max-width: 960px;
margin: 0 auto;
text-align: center;
margin-top: 60px;
}
</style>
</head>
<body>
<div class="container">
<h2>Here's the secret</h2>
<!-- This div will contain the decrypted secret (or error) -->
<div id="secret"></div>
</div>
<script>
(function() {
// Set the API key here - a public API key is required
var PUBLIC_API_KEY = "public_key_abcd...";
// ----------------------------------- //
// Get the secret ID from the query string part of the URL
// E.g. https://some.site/secret.html?secret_id
var secret_id = location.search.substr(1);
// Get the public password (encryption key) part from the hash part of the URL, in Base64 format
// E.g. https://some.site/secret.html?secret_id#password_part_public
var password_part_public = location.hash.substr(1);
// Send a request to the password.link API and process the result
$.ajax({
type: "GET",
url: "https://password.link/api/secrets/" + secret_id,
dataType: "json",
headers: {
"Authorization": "ApiKey " + PUBLIC_API_KEY
},
success: function(data) {
var secret = data.data;
decrypt_secret(password_part_public, secret.password_part_private, secret.ciphertext);
},
error: function(data) {
var error = data.responseJSON.error;
$("#secret").html("Error: " + error.message);
}
});
// A function for decrypting the secret received from the password.link API
function decrypt_secret(password_part_public, password_part_private, ciphertext) {
try {
// Decrypt the secret using SJCL
// All parameters are in Base64 format
var decrypted_secret = sjcl.decrypt(atob(password_part_private) + atob(password_part_public), atob(ciphertext));
// Set the content of the element with id "secret" to the decrypted secret
// Use .textContent to avoid XSS
document.getElementById("secret").textContent = decrypted_secret;
}
// Catch and show errors
catch(e) {
document.getElementById("secret").textContent = "Error during decryption: " + e;
}
}
})();
</script>
</body>
</html>