Ci-dessous, les différences entre deux révisions de la page.
| Prochaine révision | Révision précédente | ||
|
notes:webcrypto [2020/02/26 16:20] etienne créée |
notes:webcrypto [2021/05/28 15:12] (Version actuelle) etienne |
||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| ====== WebCrypto ====== | ====== WebCrypto ====== | ||
| + | |||
| + | Comme il est parfois difficile de faire le lien entre les formats, les algorithmes et les divers paramètres, | ||
| + | Elle ne reflète en aucun cas des méthodes devant être appliquée mais bien des exemples comme générer un clé privée avec OpenSSL et l' | ||
| ===== RSA-PSS pour signature ===== | ===== RSA-PSS pour signature ===== | ||
| + | |||
| + | [[https:// | ||
| ==== Conversion de clés ==== | ==== Conversion de clés ==== | ||
| + | |||
| + | ==== Clé publique de PEM vers DER ==== | ||
| + | <code shell> | ||
| + | $ openssl pkey -pubin -in rsapub.pem -out rsapub.der -outform DER | ||
| + | </ | ||
| + | |||
| + | |||
| + | === OpenSSH === | ||
| + | |||
| + | Pour convertir une clé SSH vers RSA (pour ensuite être utilisée avec OpenSSL) | ||
| + | <code shell> | ||
| + | $ ssh-keygen -p -m PEM -f ssh-rsa.key | ||
| + | </ | ||
| + | |||
| + | Ensuite on extrait sa clé publique et on la converti en PKCS#8 | ||
| + | <code shell> | ||
| + | $ openssl rsa -in ssh-rsa.key -pubout > ssh-rsa.pub | ||
| + | $ openssl pkcs8 -topk8 -nocrypt -in ssh-rsa.key -out ssh-rsa.pkcs8 | ||
| + | </ | ||
| === OpenSSL === | === OpenSSL === | ||
| Ligne 20: | Ligne 44: | ||
| <code javascript> | <code javascript> | ||
| - | function b64Decode (text) { | + | function b64Decode (text) { |
| - | let s = atob(text.trim().replace(/ | + | let s = atob(text.trim().replace(/ |
| - | const buffer = new ArrayBuffer(s.length) | + | const buffer = new ArrayBuffer(s.length) |
| - | const bview = new Uint8Array(buffer) | + | const bview = new Uint8Array(buffer) |
| - | for (let i = 0; i < s.length; i++) { | + | for (let i = 0; i < s.length; i++) { |
| - | | + | |
| - | | + | } |
| - | | + | |
| - | | + | } |
| - | | + | |
| - | | + | |
| - | const pemRegex = / | + | const pemRegex = / |
| - | let m = pemRegex.exec(text) | + | let m = pemRegex.exec(text) |
| - | if (m && m.length > 1) { | + | if (m && m.length > 1) { |
| - | | + | |
| - | | + | } |
| - | | + | |
| - | | + | } |
| </ | </ | ||
| Ligne 43: | Ligne 67: | ||
| <code javascript> | <code javascript> | ||
| - | | + | |
| - | let txt = '' | + | let txt = '' |
| - | let b64 = btoa(String.fromCharCode.apply(null, | + | let b64 = btoa(String.fromCharCode.apply(null, |
| - | for (let i = 0; i < (Math.ceil(b64.length / 64)); i++) { | + | for (let i = 0; i < (Math.ceil(b64.length / 64)); i++) { |
| - | txt += b64.substring(i * 64, (i + 1) * 64) + " | + | txt += b64.substring(i * 64, (i + 1) * 64) + " |
| - | | + | } |
| - | | + | |
| - | | + | } |
| - | | + | |
| - | | + | |
| - | let txt = `-----BEGIN ${priv ? ' | + | let txt = `-----BEGIN ${priv ? ' |
| - | txt += b64Encode(buffer) | + | txt += b64Encode(buffer) |
| - | | + | |
| - | | + | } |
| </ | </ | ||
| ==== Génération de clés ==== | ==== Génération de clés ==== | ||
| + | |||
| + | |||
| === OpenSSL === | === OpenSSL === | ||
| Ligne 69: | Ligne 95: | ||
| $ openssl rsa -in rsakey.pem -pubout > rsapub.pem # clé publique | $ openssl rsa -in rsakey.pem -pubout > rsapub.pem # clé publique | ||
| </ | </ | ||
| + | |||
| + | === SSH === | ||
| + | |||
| + | OpenSSH génère des clé au format RFC4716. | ||
| + | <code shell> | ||
| + | $ ssh-keygen -t rsa -b 2048 -f ssh-rsa.key | ||
| + | </ | ||
| + | |||
| + | Avec l' | ||
| === JavaScript === | === JavaScript === | ||
| <code javascript> | <code javascript> | ||
| - | | + | |
| - | | + | |
| - | /* same as openssl genrsa -F4 2048 */ | + | /* same as openssl genrsa -F4 2048 */ |
| - | | + | |
| - | | + | { |
| - | name: ' | + | name: ' |
| - | hash: ' | + | hash: ' |
| - | | + | |
| - | | + | |
| - | | + | }, |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | }) |
| - | | + | }) |
| - | | + | }) |
| } | } | ||
| </ | </ | ||
| + | |||
| + | ==== Création de signature ==== | ||
| + | === OpenSSL === | ||
| + | |||
| + | <code shell> | ||
| + | echo -n "Texte à signer" | ||
| + | </ | ||
| + | |||
| + | === JavaScript === | ||
| + | <code javascript> | ||
| + | | ||
| + | | ||
| + | const key = readPEM(privkey) | ||
| + | if (key) { | ||
| + | | ||
| + | ' | ||
| + | key, | ||
| + | { | ||
| + | name: ' | ||
| + | hash: { name: ' | ||
| + | }, | ||
| + | | ||
| + | [ ' | ||
| + | | ||
| + | | ||
| + | { | ||
| + | name: ' | ||
| + | }, | ||
| + | key, | ||
| + | (new TextEncoder).encode(text) | ||
| + | | ||
| + | | ||
| + | }) | ||
| + | }) | ||
| + | } | ||
| + | }) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === PHP/ | ||
| + | |||
| + | Signature avec [[http:// | ||
| + | |||
| + | <code php> | ||
| + | <?PHP | ||
| + | require(' | ||
| + | use phpseclib\Crypt\RSA; | ||
| + | |||
| + | $rsa = new RSA(); | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $text = 'Texte à signer'; | ||
| + | $signature = $rsa-> | ||
| + | echo base64_encode($signature); | ||
| + | ?> | ||
| + | </ | ||
| + | |||
| + | === C/OpenSSL EVP === | ||
| + | |||
| + | <code c> | ||
| + | /* Pour lire la clé : | ||
| + | | ||
| + | * FILE * fp = fopen(" | ||
| + | * sign(PEM_read_PrivateKey(fp, | ||
| + | */ | ||
| + | |||
| + | void sign (EVP_PKEY * pkey, const char * text, unsigned char ** stext, size_t * slen) { | ||
| + | size_t siglen = 0; | ||
| + | EVP_PKEY_CTX * kctx = NULL; | ||
| + | EVP_MD_CTX * mctx = NULL; | ||
| + | |||
| + | mctx = EVP_MD_CTX_new(); | ||
| + | if (!mctx) { return; } | ||
| + | | ||
| + | kctx = EVP_PKEY_CTX_new(pkey, | ||
| + | if (kctx) { | ||
| + | /* ordre important ici */ | ||
| + | EVP_MD_CTX_set_pkey_ctx(mctx, | ||
| + | EVP_DigestSignInit(mctx, | ||
| + | |||
| + | EVP_PKEY_CTX_set_rsa_padding(kctx, | ||
| + | EVP_PKEY_CTX_set_signature_md(kctx, | ||
| + | EVP_PKEY_CTX_set_rsa_mgf1_md(kctx, | ||
| + | EVP_PKEY_CTX_set_rsa_pss_saltlen(kctx, | ||
| + | |||
| + | EVP_DigestSignUpdate(mctx, | ||
| + | EVP_DigestSignFinal(mctx, | ||
| + | | ||
| + | *stext = calloc(siglen, | ||
| + | if (*stext == NULL) { | ||
| + | EVP_MD_CTX_free(mctx); | ||
| + | return; | ||
| + | } | ||
| + | EVP_DigestSignFinal(mctx, | ||
| + | *slen = siglen; | ||
| + | } | ||
| + | EVP_MD_CTX_free(mctx); | ||
| + | | ||
| + | return; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Vérification de signature ==== | ||
| + | |||
| + | === OpenSSL === | ||
| + | <code shell> | ||
| + | $ base64 -d < fromjs.sig - > fromjs.bin.sig | ||
| + | $ echo -n "Texte à signer" | ||
| + | </ | ||
| + | |||
| + | === JavaScript === | ||
| + | <code javascript> | ||
| + | | ||
| + | | ||
| + | const cert = readPEM(pubkey) | ||
| + | if (cert) { | ||
| + | | ||
| + | ' | ||
| + | cert, | ||
| + | { | ||
| + | name: ' | ||
| + | hash: { name: ' | ||
| + | }, | ||
| + | | ||
| + | [ ' | ||
| + | | ||
| + | | ||
| + | { | ||
| + | name: ' | ||
| + | }, | ||
| + | key, | ||
| + | | ||
| + | (new TextEncoder).encode(text) | ||
| + | | ||
| + | | ||
| + | }) | ||
| + | }) | ||
| + | } | ||
| + | }) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === PHP/ | ||
| + | |||
| + | L' | ||
| + | |||
| + | <code php> | ||
| + | <?PHP | ||
| + | $rsa = new RSA(); | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $rsa-> | ||
| + | $text = 'Texte à signer'; | ||
| + | echo $rsa-> | ||
| + | ?> | ||
| + | </ | ||
| + | |||