diff --git a/duniterpy/documents/certification.py b/duniterpy/documents/certification.py
index 9b3b857b2aa9932532063ae067c5ebcee254bc4f..0ee90038820afd95b6ee59ac3891fa299d6f8da8 100644
--- a/duniterpy/documents/certification.py
+++ b/duniterpy/documents/certification.py
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
-from typing import Optional, Type, TypeVar, Union
+from typing import Any, Optional, Type, TypeVar, Union
 
 from ..constants import (
     BLOCK_ID_REGEX,
@@ -80,6 +80,31 @@ class Certification(Document):
         if signing_key is not None:
             self.sign(signing_key)
 
+    def __eq__(self, other: Any) -> bool:
+        """
+        Check Certification instances equality
+        """
+        if not isinstance(other, Certification):
+            return NotImplemented
+        return (
+            super().__eq__(other)
+            and self.pubkey_from == other.pubkey_from
+            and self.identity == other.identity
+            and self.block_id == other.block_id
+        )
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.pubkey_from,
+                self.identity,
+                self.block_id,
+                self.version,
+                self.currency,
+                self.signature,
+            )
+        )
+
     @classmethod
     def from_signed_raw(
         cls: Type[CertificationType], signed_raw: str
diff --git a/tests/documents/test_certification.py b/tests/documents/test_certification.py
index 94ee536550d2ecf397d8b5a9f9ab73f4a2da5116..dfee42c96a90e2a18fe9e96eca6de71c13678a87 100644
--- a/tests/documents/test_certification.py
+++ b/tests/documents/test_certification.py
@@ -15,11 +15,16 @@
 
 import unittest
 
-from duniterpy.constants import EMPTY_HASH
+import pytest
+
+from duniterpy.constants import EMPTY_HASH, G1_TEST_CURRENCY_CODENAME
+from duniterpy.documents import Certification, Identity, Revocation
 from duniterpy.documents.block import BlockID
-from duniterpy.documents.certification import Certification
-from duniterpy.documents.identity import Identity
-from duniterpy.documents.revocation import Revocation
+
+PUBKEY = "A"
+UID = "test"
+BLOCK_ID = "0-NRSATU"
+IDENTITY_KWARGS = [PUBKEY, UID, BLOCK_ID]
 
 selfcert_inlines = [
     "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:\
@@ -223,3 +228,27 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN
         revocation = Revocation.from_signed_raw(signed_raw)
         self.assertTrue(isinstance(Revocation.extract_self_cert(signed_raw), Identity))
         self.assertEqual(revocation.signed_raw(), signed_raw)
+
+
+def test_certification_equality():
+    cert1 = Certification(PUBKEY, Identity(*IDENTITY_KWARGS), BLOCK_ID)
+    cert2 = Certification(PUBKEY, Identity(*IDENTITY_KWARGS), BLOCK_ID)
+    assert cert1 == cert2
+
+
+@pytest.mark.parametrize(
+    "pubkey, uid, block_id, currency",
+    [
+        ("pubkey", UID, BLOCK_ID, None),
+        (PUBKEY, "uid", BLOCK_ID, None),
+        (PUBKEY, UID, "1-TEST", None),
+        IDENTITY_KWARGS + [G1_TEST_CURRENCY_CODENAME],
+    ],
+)
+def test_certification_inequality(pubkey, uid, block_id, currency):
+    cert1 = Certification(pubkey, Identity(*IDENTITY_KWARGS), block_id)
+    idty2 = Identity(pubkey, uid, block_id)
+    cert2 = Certification(pubkey, idty2, block_id)
+    if currency:
+        cert2.currency = currency
+    assert not cert1 == cert2