[CC][API] Cryptographie Délocalisée
2 participants
Page 1 sur 1
[CC][API] Cryptographie Délocalisée
Bonjour, je vais vous présenter ce que je vais appeler mon API de Cryptographie délocalisée (notez le nom très original) :
Le principe est simple: minimiser les opérations du côté LUA pour:
Pour atteindre ce but, j'ai choisi de coder une simple page PHP qui répond à des requêtes POST.
L'API fait simplement des requêtes à la page et le serveur web prend en charge tous les calculs 'lourds'.
Le code LUA prend en charge lui toutes les spécificités de l'appel à la page pour diminuer au maximum la complexité de l'API.
Sans plus attendre, voici le code CC:
Pour remédier à ça, je vous incite vivement à héberger vous même la page PHP (ça m'arrange, ça diminue le load sur mon VPS )
Le principe est simple: minimiser les opérations du côté LUA pour:
- Améliorer la vitesse des opérations.
- Réduire l'impact sur le serveur MC.
- Utiliser les fonctions de Crypto optimisées d'un environnement moins restreint que celui de CC.
Pour atteindre ce but, j'ai choisi de coder une simple page PHP qui répond à des requêtes POST.
L'API fait simplement des requêtes à la page et le serveur web prend en charge tous les calculs 'lourds'.
Le code LUA prend en charge lui toutes les spécificités de l'appel à la page pour diminuer au maximum la complexité de l'API.
Sans plus attendre, voici le code CC:
- Spoiler:
Pastebin: ZRpFhBbF- Code:
local host = "- EDIT: Je peux pas encore poster de liens ^^ (Il est dans le pastebin)-"
--TODO:
-- /
local function request(host, data)
local postdata = ""
for k,v in pairs(data) do
postdata = postdata .. "&" .. textutils.urlEncode(k) .. "=" .. textutils.urlEncode(v)
end
postdata = postdata:sub(2)
local ret = http.post(host, postdata)
local data = ret.readAll()
ret.close()
return data
end
function generate()
local data = request(host, {
func = "generate"
})
return textutils.unserialise(data)
end
function encrypt(data, key)
if not data then error("No data given") end
if not key then error("No key given") end
if not type(key)=="string" then error("Key must be a string") end
if data=="" then return "" end
local ret = request(host, {
func = "encrypt",
data = textutils.serialise(data),
key = key
})
if ret=="" then error("Error during encryption") end
return ret
end
function decrypt(crypted, key)
if not crypted then error("No data given") end
if not key then error("No key given") end
if not type(key)=="string" then error("Key must be a string") end
if not type(crypted)=="string" then error("Crypted data must be a string") end
if crypted=="" then return "" end
local ret = request(host, {
func = "decrypt",
data = crypted,
key = key
})
if ret=="" then error("Error during decryption") end
return textutils.unserialise(ret)
end
function sign(data, key)
if not data then error("No data given") end
if not key then error("No key given") end
if not type(key)=="string" then error("Key must be a string") end
local ret = request(host, {
func = "sign",
data = textutils.serialise(data),
key = key
})
if ret=="ERROR" then error("Error during signature") end
return ret
end
function verify(signed, original, key)
if not data then error("No data given") end
if not original then error("No test given") end
if not key then error("No key given") end
if not type(key)=="string" then error("Key must be a string") end
if not type(signed)=="string" then error("Signature must be a string") end
local ret request(host, {
func = "verify",
data = signed,
original = textutils.serialise(original),
key = key
})
if ret=="ERROR" then error("Error during verification") end
return ret == "1"
end
- doc:
PS: désolé pour le formattage horribleFonction Paramètres valeur Retournée generate / -une table contenant les clés 'public' et 'private' encrypt
(à utiliser avec decrypt)-un valeur à encrypter (tout type)
-une clé publique (string)-les données encryptées (string) decrypt
(à utiliser avec encrypt)-une valeur encryptée (string)
-la clé privée (string)-la valeur décryptée (tout type) sign
(à utiliser avec verify)-une valeur pour créer la signature (tout type)
-une clé privée (string)-Le hash de la valeur, encrypté avec la clé (string) verify
(à utiliser avec sign)-le hash encrypté de sign (string)
-la valeur originale (tout type)
-la clé publique (string)-si la valeur correspond à la signature (booléen)
Pour remédier à ça, je vous incite vivement à héberger vous même la page PHP (ça m'arrange, ça diminue le load sur mon VPS )
- Attention, c'est pas joli:
Pastebin: 0jXBPteP- Code:
<?php
if(!isset($_POST['func'])) {exit('{}');}
$config = array(
"digest_alg" => "sha512",
"private_key_bits" => 1024,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
//Crédit à gutzmer[..] pour ces 2 fonctions (- Voir le pastebin -)
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
function encrypt($data, $keytext) {
$key = openssl_get_publickey($keytext);
if($key===false) {
return '';
}
openssl_seal($data, $crypted, $keys, array($key));
$encoded = base64url_encode(base64url_encode($crypted).':'.base64url_encode($keys[0]));
openssl_free_key($key);
return $encoded;
}
function decrypt($crypted, $keytext) {
$key = openssl_get_privatekey($keytext);
if($key===false) {
return '';
}
$decoded = explode(':',base64url_decode($crypted));
openssl_open(base64url_decode($decoded[0]), $data, base64url_decode($decoded[1]), $key);
openssl_free_key($key);
return $data;
}
function sign($data, $keytext) {
$key = openssl_get_privatekey($keytext);
if($key===false) {
return '';
}
$datasig = base64url_encode(openssl_digest($data, "SHA256"));
$ok = openssl_private_encrypt($datasig, $signed, $key);
openssl_free_key($key);
return $ok?base64url_encode($signed):'ERROR';
}
function verify($data, $signed, $keytext) {
$key = openssl_get_publickey($keytext);
if($key===false) {
return '';
}
$datasig = base64url_encode(openssl_digest($data, "SHA256"));
$ok = openssl_public_decrypt(base64url_decode($signed), $testsig, $key);
openssl_free_key($key);
return $ok?($datasig==$testsig?1:0):'ERROR';
}
switch($_POST['func']) {
case 'encrypt':
if(!isset($_POST['data']) || !isset($_POST['key'])) {exit('');}
$key = base64url_decode($_POST['key']);
echo encrypt($_POST['data'], $key);
break;
case 'decrypt':
if(!isset($_POST['data']) || !isset($_POST['key'])) {exit('');}
$key = base64url_decode($_POST['key']);
echo decrypt($_POST['data'], $key);
break;
case 'generate':
$keys = openssl_pkey_new($config);
openssl_pkey_export($keys, $private);
$public = openssl_pkey_get_details($keys)["key"];
echo('{private="' . base64url_encode($private) . '",public="' . base64url_encode($public) . '"}');
break;
case 'sign':
if(!isset($_POST['data']) || !isset($_POST['key'])) {exit('');}
$key = base64url_decode($_POST['key']);
echo sign($_POST['data'], $key);
break;
case 'verify':
if(!isset($_POST['data']) || !isset($_POST['key']) || !isset($_POST['original'])) {exit('');}
$key = base64url_decode($_POST['key']);
echo verify($_POST['original'], $_POST['data'], $key);
break;
}
?>
Dernière édition par Thomasims le Mer 17 Aoû - 19:21, édité 1 fois
Thomasims- Messages : 3
Date d'inscription : 11/08/2016
Age : 26
Localisation : Belgique
Re: [CC][API] Cryptographie Délocalisée
Tu peux faire un meilleur usage de LUA dans le contrôle et la gestion des erreurs.
Par exemple, pour une série comme ça :
Tu devrais pouvoir utiliser la fonction assert()
ref: https://www.lua.org/pil/8.3.html
Enfin, la fonction error() peut prendre un second paramètre qui par défaut est à 1 et correspond au level : à quelle ligne de quel programme l'erreur doit être signalée.
Tel quel, si un utilisateur de ton api commet une erreur, en retour il lui sera signalé que l'erreur proviens de l'api, et non du programme où l'utilisateur a commis l'erreur.
Pour que le signalement de l'erreur soit plus cohérent, il suffirait d'indiquer le level 2 :
Exemple :
On peut aussi faire en sorte qu'il ne soit pas fait mention de la ligne ou du fichier, en indiquant le level 0 (zéro)
Jusque là je croyais que c'était -1, qui fonctionne aussi enfin maintenant je le sais
réf: https://www.lua.org/pil/8.5.html
Enfin je ne crois pas que assert() gère le level. Mais l'une sinon l'autre de ces deux astuces devrait bien te servir
Par exemple, pour une série comme ça :
- Code:
if not data then error("No data given") end
if not original then error("No test given") end
if not key then error("No key given") end
if not type(key)=="string" then error("Key must be a string") end
if not type(signed)=="string" then error("Signature must be a string") end
Tu devrais pouvoir utiliser la fonction assert()
- Code:
assert(data, "No data given")
assert(original, "No test given")
assert(key, "No key given")
assert(type(key)=="string", "Key must be a string")
assert(type(signed)=="string", "Signature must be a string")
ref: https://www.lua.org/pil/8.3.html
Enfin, la fonction error() peut prendre un second paramètre qui par défaut est à 1 et correspond au level : à quelle ligne de quel programme l'erreur doit être signalée.
Tel quel, si un utilisateur de ton api commet une erreur, en retour il lui sera signalé que l'erreur proviens de l'api, et non du programme où l'utilisateur a commis l'erreur.
Pour que le signalement de l'erreur soit plus cohérent, il suffirait d'indiquer le level 2 :
Exemple :
- Code:
function encrypt(data, key)
if not data then error("No data given",2) end
if not key then error("No key given",2) end
-- ...
On peut aussi faire en sorte qu'il ne soit pas fait mention de la ligne ou du fichier, en indiquant le level 0 (zéro)
Jusque là je croyais que c'était -1, qui fonctionne aussi enfin maintenant je le sais
réf: https://www.lua.org/pil/8.5.html
Enfin je ne crois pas que assert() gère le level. Mais l'une sinon l'autre de ces deux astuces devrait bien te servir
skypop- Messages : 95
Date d'inscription : 25/07/2016
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum