diff --git a/CHANGELOG.fr.md b/CHANGELOG.fr.md
index bdda49c6ceb976d13893df6e7992d7b7cbbc1cb1..448826a02b014899406d9515c42f1544eea13f69 100644
--- a/CHANGELOG.fr.md
+++ b/CHANGELOG.fr.md
@@ -13,6 +13,10 @@ et ce projet adhère au [versionnage sémantique](https://semver.org/spec/v2.0.0
 
 ## [Non-publié/Non-Stabilisé] (par [1000i100])
 
+## [Version 3.4.1] - 2022-11-20 (par [1000i100])
+### Corrections
+- checkKey envoi désormais des erreurs nommées, utilisable pour guider les usagers.
+
 ## [Version 3.4.0] - 2022-11-15 (par [1000i100])
 ### Ajouté
 - crypto.textEncrypt(jsonMessage, senderPrivateKey, receiverPubKey) retourne un json format cesium+ avec `jsonMessage.title` et `jsonMessage.content` chiffrés.
@@ -101,8 +105,9 @@ et ce projet adhère au [versionnage sémantique](https://semver.org/spec/v2.0.0
 - intégration des librairies de crypto nécessaires
 - calcul de la clef publique correspondant à chaque combinaison de secrets saisie, et comparaison à la clef publique de référence.
 
-[Non-publié/Non-Stabilisé]: https://git.duniter.org/libs/g1lib.js/-/compare/v3.4.0...main
+[Non-publié/Non-Stabilisé]: https://git.duniter.org/libs/g1lib.js/-/compare/v3.4.1...main
 
+[Version 3.4.1]: https://git.duniter.org/libs/g1lib.js/-/compare/v3.4.0...v3.4.1
 [Version 3.4.0]: https://git.duniter.org/libs/g1lib.js/-/compare/v3.3.3...v3.4.0
 [Version 3.3.3]: https://git.duniter.org/libs/g1lib.js/-/compare/v3.3.2...v3.3.3
 [Version 3.3.2]: https://git.duniter.org/libs/g1lib.js/-/compare/v3.3.1...v3.3.2
diff --git a/npm/package.json b/npm/package.json
index df79b1f275a7c7fba6b44887fcd9253987357f0a..277098002b7697316fff7a38953cff31fe8dbcf4 100644
--- a/npm/package.json
+++ b/npm/package.json
@@ -1,6 +1,6 @@
 {
   "name": "g1lib",
-  "version": "3.4.0",
+  "version": "3.4.1",
   "description": "An ubiquitous static javascript toolbox lib for Ǧ1 / Duniter ecosystem with reliability in mind.",
   "main": "nodejs/all.mjs",
 	"browser": "browser/all.mjs",
diff --git a/src/crypto.mjs b/src/crypto.mjs
index cac959e77e4e88e45542717ed928ed6a2861b609..36d66f6d625bc29eaef275d90e4838afdb8e8802 100644
--- a/src/crypto.mjs
+++ b/src/crypto.mjs
@@ -121,14 +121,25 @@ export function onlyPubKey(pubKeyWithChecksum){
 	if (pubKey2checksum(b58pubKey, true, false, false) === checkSum) return b58pubKey;
 	if (pubKey2checksum(b58pubKey, false, true, false) === checkSum) return b58pubKey;
 	if (pubKey2checksum(b58pubKey, true, true, false) === checkSum) return b58pubKey;
-	throw new Error('Bad checksum');
+	throw new CustomError('bad_checksum','Bad checksum');
 }
 export function isDuniterPubKey(b58pubKey){
 	return /^[A-HJ-NP-Za-km-z1-9]{43,44}$/.test(b58pubKey) && b58.decode(b58pubKey).length <=32;
 }
+export function checkDuniterPubKey(b58pubKey){
+	if(b58pubKey.length<43) throw new CustomError('too_short','Too short, see rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key for details.');
+	if(b58pubKey.length>44) throw new CustomError('too_long','Base58 string too long, see rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key for details.');
+	if(!/^[A-HJ-NP-Za-km-z1-9]+$/.test(b58pubKey)) throw new CustomError('not_b58', 'Character out of base 58, see rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key for details.');
+	if(b58.decode(b58pubKey).length > 32) throw new CustomError('too_long','binary key too long, see rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key for details.');
+	return true;
+}
 export function checkEd25519PubKey(b58pubKey){
 	const binPubKey = pubKey2bin(b58pubKey);
-	ed25519.Point.fromHex(binPubKey);
+	try{
+		ed25519.Point.fromHex(binPubKey);
+	} catch (err){
+		throw new CustomError('bad_ed25519_point',`Invalid public key : not a valid ed25519 point RFC8032 5.1.3 https://www.rfc-editor.org/rfc/rfc8032#page-11 Internal:${err}`);
+	}
 	return true;
 }
 export function isEd25519PubKey(b58pubKey){
@@ -138,11 +149,19 @@ export function isEd25519PubKey(b58pubKey){
 }
 
 export function checkKey(pubKey, checkRawPubKey= true) {
-	const binPubKey = pubKey2bin(pubKey)
-	const b58pubKey = b58.encode(binPubKey);
+	if(!pubKey) throw new CustomError('empty','Invalid public key : empty input.')
+	let b58pubKey;
+	try {
+		const binPubKey = pubKey2bin(pubKey)
+		b58pubKey = b58.encode(binPubKey);
+	} catch (err){
+		if(err.message.match(/base58/)) throw new CustomError('not_b58', 'Character out of base 58, see rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key for details.');
+		if(err.message.match(/out of bounds/)) throw new CustomError('too_long','Binary key too long, see rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key for details.');
+		throw err;
+	}
 	if(!checkRawPubKey) return true;
-	if(!isDuniterPubKey(b58pubKey)) throw new Error("Invalid public key : this string don't follow rfc/0009_Duniter_Blockchain_Protocol_V11.md#public-key");
-	if(!isEd25519PubKey(b58pubKey)) throw new Error("Invalid public key : not a valid ed25519 point RFC8032 5.1.3 https://www.rfc-editor.org/rfc/rfc8032#page-11");
+	checkDuniterPubKey(b58pubKey);
+	checkEd25519PubKey(b58pubKey);
 	return true;
 }
 export function isPubKey(pubKey){
@@ -229,3 +248,9 @@ export function textDecrypt(jsonMessage, receiverPrivateKey){
 	if(jsonMessage.title) res.title = decrypt(jsonMessage.title);
 	return res;
 }
+class CustomError extends Error {
+	constructor(name, message) {
+		super(message);
+		this.name = name;
+	}
+}
diff --git a/src/crypto.test.mjs b/src/crypto.test.mjs
index 2c45600463d3c1169e7371f44ccf5de969b144dd..6c07e9b88a4dca01f685b9f4ce9f010220d66ef1 100644
--- a/src/crypto.test.mjs
+++ b/src/crypto.test.mjs
@@ -128,8 +128,12 @@ test("isEd25519PubKey fail if point is not on ed25519", (t) => t.false(app.isEd2
 
 
 test('checkKey accept valid pubKey with no checksum', t => t.true(app.checkKey(pubKey)));
-test('checkKey throw if invalid pubkey is given', t => t.throws(() => app.checkKey(pubKey.replace(/6/,'9'))));
-test('checkKey throw if empty pubkey is given', t => t.throws(() => app.checkKey('')));
+test('checkKey throw if empty pubkey is given', t => t.throws(() => app.checkKey(''),{name:'empty'}));
+test('checkKey throw if under_sized string is given', t => t.throws(() => app.checkKey('test'),{name:'too_short'}));
+test('checkKey throw if over_sized string is given', t => t.throws(() => app.checkKey(pubKey+pubKey),{name:'too_long'}));
+test('checkKey throw if invalid pubkey is given (not on ed25519 curve)', t => t.throws(() => app.checkKey(pubKey.replace(/6/,'9')),{name:'bad_ed25519_point'}));
+test('checkKey throw if checksum is incorrect', t => t.throws(() => app.checkKey(`${pubKey}:111`),{name:'bad_checksum'}));
+test('checkKey throw if not b58 string is given', t => t.throws(() => app.checkKey(`___`),{name:'not_b58'}));
 
 test('checkKey accept valid binary pubKey', t => t.true(app.checkKey(app.b58.decode(pubKey))));