diff --git a/src/ECP256Certificate.cpp b/src/ECP256Certificate.cpp
index 1cf5de5..e146a2f 100644
--- a/src/ECP256Certificate.cpp
+++ b/src/ECP256Certificate.cpp
@@ -12,6 +12,9 @@
  * INCLUDE
  ******************************************************************************/
 
+/* This is needed for memmem */
+#define _GNU_SOURCE
+#include <string.h>
 #include "ECP256Certificate.h"
 
 /******************************************************************************
@@ -300,6 +303,16 @@ int ECP256Certificate::importCert(const byte certDER[], size_t derLen)
 
   memcpy(_certBuffer, certDER, _certBufferLen);
 
+  /* Import Authority Key Identifier to compressed cert struct */
+  if (!importCompressedAuthorityKeyIdentifier()) {
+    return 0;
+  }
+
+  /* Import signature to compressed cert struct */
+  if (!importCompressedSignature()) {
+    return 0;
+  }
+
   return 1;
 }
 
@@ -901,3 +914,80 @@ int ECP256Certificate::appendAuthorityKeyId(const byte authorityKeyId[], int len
 
   return length + 17;
 }
+
+int ECP256Certificate::importCompressedAuthorityKeyIdentifier() {
+  static const byte objectId[] = {0x06, 0x03, 0x55, 0x1D, 0x23};
+  byte * result = nullptr;
+  void * ptr = memmem(_certBuffer, _certBufferLen, objectId, sizeof(objectId));
+  if (ptr != nullptr) {
+    result = (byte*)ptr;
+    result += 11;
+    memcpy(_compressedCert.slot.two.values.authorityKeyId, result, ECP256_CERT_AUTHORITY_KEY_ID_LENGTH);
+    return 1;
+  }
+  return 0;
+}
+
+int ECP256Certificate::importCompressedSignature() {
+  byte * result = nullptr;
+  byte paddingBytes = 0;
+  byte rLen = 0;
+  byte sLen = 0;
+
+  /* Search AuthorityKeyIdentifier */
+  static const byte KeyId[] = {0x06, 0x03, 0x55, 0x1D, 0x23};
+  void * ptr = memmem(_certBuffer, _certBufferLen, KeyId, sizeof(KeyId));
+  if(ptr == nullptr) {
+    return 0;
+  }
+  result = (byte*)ptr;
+
+  /* Search Algorithm identifier */
+  static const byte AlgId[] = {0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
+  ptr = memmem(result, _certBufferLen - (_certBuffer - result), AlgId, sizeof(AlgId));
+  if(ptr == nullptr) {
+    return 0;
+  }
+  result = (byte*)ptr;
+
+  /* Skip algorithm identifier */
+  result += sizeof(AlgId);
+
+  /* Search signature sequence */
+  if (result[0] == 0x03) {
+    /* Move to  the first element of R sequence skipping 0x03 0x49 0x00 0x30 0xXX*/
+    result += 5;
+    /* Check if value is padded */
+    if (result[0] == 0x02 && result[1] == 0x21 && result[2] == 0x00) {
+      paddingBytes = 1;
+    }
+    rLen = result[1] - paddingBytes;
+    /* Skip padding and ASN INTEGER sequence 0x02 0xXX */
+    result += (2 + paddingBytes);
+    /* Check data length */
+    if (rLen != ECP256_CERT_SIGNATURE_R_LENGTH) {
+      return 0;
+    }
+    /* Copy data to compressed slot */
+    memcpy(_compressedCert.slot.one.values.signature, result, rLen);
+    /* reset padding before importing S sequence */
+    paddingBytes = 0;
+    /* Move to the first element of S sequence skipping R values */
+    result += rLen;
+    /* Check if value is padded */
+    if (result[0] == 0x02 && result[1] == 0x21 && result[2] == 0x00) {
+      paddingBytes = 1;
+    }
+    sLen = result[1] - paddingBytes;
+    /* Skip padding and ASN INTEGER sequence 0x02 0xXX */
+    result += (2 + paddingBytes);
+    /* Check data length */
+    if (sLen != ECP256_CERT_SIGNATURE_S_LENGTH) {
+      return 0;
+    }
+    /* Copy data to compressed slot */
+    memcpy(&_compressedCert.slot.one.values.signature[rLen], result, sLen);
+    return 1;
+  }
+  return 0;
+}
diff --git a/src/ECP256Certificate.h b/src/ECP256Certificate.h
index 4e065df..2be7c5c 100644
--- a/src/ECP256Certificate.h
+++ b/src/ECP256Certificate.h
@@ -22,10 +22,12 @@
 #define ECP256_CERT_SERIAL_NUMBER_LENGTH            16
 #define ECP256_CERT_AUTHORITY_KEY_ID_LENGTH         20
 #define ECP256_CERT_PUBLIC_KEY_LENGTH               64
-#define ECP256_CERT_SIGNATURE_LENGTH                64
+#define ECP256_CERT_SIGNATURE_R_LENGTH              32
+#define ECP256_CERT_SIGNATURE_S_LENGTH              ECP256_CERT_SIGNATURE_R_LENGTH
+#define ECP256_CERT_SIGNATURE_LENGTH                (ECP256_CERT_SIGNATURE_R_LENGTH + ECP256_CERT_SIGNATURE_S_LENGTH)
 #define ECP256_CERT_DATES_LENGTH                     3
 #define ECP256_CERT_COMPRESSED_CERT_SLOT_LENGTH     72
-#define ECP256_CERT_COMPRESSED_CERT_LENGTH         ECP256_CERT_COMPRESSED_CERT_SLOT_LENGTH + ECP256_CERT_SERIAL_NUMBER_LENGTH + ECP256_CERT_AUTHORITY_KEY_ID_LENGTH
+#define ECP256_CERT_COMPRESSED_CERT_LENGTH          (ECP256_CERT_COMPRESSED_CERT_SLOT_LENGTH + ECP256_CERT_SERIAL_NUMBER_LENGTH + ECP256_CERT_AUTHORITY_KEY_ID_LENGTH)
 
 #include <Arduino.h>
 
@@ -81,6 +83,9 @@ class ECP256Certificate {
   inline byte* subjectCommonNameBytes() { return (byte*)_subjectData.commonName.begin(); }
   inline int subjectCommonNameLenght() {return _subjectData.commonName.length(); }
 
+  inline const byte* authorityKeyIdentifierBytes() { return _compressedCert.slot.two.values.authorityKeyId; }
+  inline const byte* signatureBytes() { return _compressedCert.slot.one.values.signature; }
+
   /* Build CSR */
   int buildCSR();
   int signCSR(byte signature[]);
@@ -173,6 +178,9 @@ class ECP256Certificate {
   int appendEcdsaWithSHA256(byte out[]);
   int appendAuthorityKeyId(const byte authorityKeyId[], int length, byte out[]);
 
+  int importCompressedAuthorityKeyIdentifier();
+  int importCompressedSignature();
+
 };
 
 #endif /* ECP256_CERTIFICATE_H */
diff --git a/src/SecureElementConfig.h b/src/SecureElementConfig.h
index 12815d0..064afb7 100644
--- a/src/SecureElementConfig.h
+++ b/src/SecureElementConfig.h
@@ -29,4 +29,30 @@
   #define SECURE_ELEMENT_IS_SOFTSE
 #endif
 
+#if defined __has_include
+  #if __has_include (<Arduino_DebugUtils.h>)
+    #include <Arduino_DebugUtils.h>
+  #endif
+#endif
+
+#ifndef DEBUG_ERROR
+  #define DEBUG_ERROR(fmt, ...)
+#endif
+
+#ifndef DEBUG_WARNING
+  #define DEBUG_WARNING(fmt, ...)
+#endif
+
+#ifndef DEBUG_INFO
+  #define DEBUG_INFO(fmt, ...)
+#endif
+
+#ifndef DEBUG_DEBUG
+  #define DEBUG_DEBUG(fmt, ...)
+#endif
+
+#ifndef DEBUG_VERBOSE
+  #define DEBUG_VERBOSE(fmt, ...)
+#endif
+
 #endif /* SECURE_ELEMENT_CONFIG_H_ */
diff --git a/src/utility/SElementArduinoCloudCertificate.cpp b/src/utility/SElementArduinoCloudCertificate.cpp
index e44ccd2..598e5a5 100644
--- a/src/utility/SElementArduinoCloudCertificate.cpp
+++ b/src/utility/SElementArduinoCloudCertificate.cpp
@@ -14,6 +14,39 @@
 
 #include <utility/SElementArduinoCloudCertificate.h>
 
+/******************************************************************************
+ * LOCAL MODULE FUNCTIONS
+ ******************************************************************************/
+
+static void hexStringToBytes(String in, byte out[], int length) {
+  int inLength = in.length();
+  in.toUpperCase();
+  int outLength = 0;
+
+  for (int i = 0; i < inLength && outLength < length; i += 2) {
+    char highChar = in[i];
+    char lowChar = in[i + 1];
+
+    byte highByte = (highChar <= '9') ? (highChar - '0') : (highChar + 10 - 'A');
+    byte lowByte = (lowChar <= '9') ? (lowChar - '0') : (lowChar + 10 - 'A');
+
+    out[outLength++] = (highByte << 4) | (lowByte & 0xF);
+  }
+}
+
+/******************************************************************************
+ * STATIC MEMBER DEFINITIONS
+ ******************************************************************************/
+
+const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_COUNTRY_NAME[];
+const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_ORGANIZATION_NAME[];
+const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME[];
+const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_COMMON_NAME[];
+
+/******************************************************************************
+ * PUBLIC MEMBER FUNCTIONS
+ ******************************************************************************/
+
 int SElementArduinoCloudCertificate::write(SecureElement & se, ECP256Certificate & cert, const SElementArduinoCloudSlot certSlot)
 {
 #if defined(SECURE_ELEMENT_IS_SE050) || defined(SECURE_ELEMENT_IS_SOFTSE)
@@ -73,10 +106,10 @@ int SElementArduinoCloudCertificate::read(SecureElement & se, ECP256Certificate
   }
 
   cert.setSubjectCommonName(deviceId);
-  cert.setIssuerCountryName("US");
-  cert.setIssuerOrganizationName("Arduino LLC US");
-  cert.setIssuerOrganizationalUnitName("IT");
-  cert.setIssuerCommonName("Arduino");
+  cert.setIssuerCountryName(SEACC_ISSUER_COUNTRY_NAME);
+  cert.setIssuerOrganizationName(SEACC_ISSUER_ORGANIZATION_NAME);
+  cert.setIssuerOrganizationalUnitName(SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME);
+  cert.setIssuerCommonName(SEACC_ISSUER_COMMON_NAME);
 
   if (!cert.setPublicKey(publicKey, ECP256_CERT_PUBLIC_KEY_LENGTH)) {
     return 0;
@@ -92,3 +125,68 @@ int SElementArduinoCloudCertificate::read(SecureElement & se, ECP256Certificate
 #endif
   return 1;
 }
+
+int SElementArduinoCloudCertificate::signatureCompare(const byte * signatureA, const String & signatureB)
+{
+  byte signatureBytes[ECP256_CERT_SIGNATURE_LENGTH];
+
+  if (signatureB.length() == 0 || signatureA == nullptr) {
+    DEBUG_ERROR("SEACC::%s input params error.", __FUNCTION__);
+    return -1;
+  }
+
+  hexStringToBytes(signatureB, signatureBytes, sizeof(signatureBytes));
+
+  /* If authorityKeyId are matching there is no need to rebuild*/
+  if (memcmp(signatureBytes, signatureA , sizeof(signatureBytes)) == 0) {
+    DEBUG_VERBOSE("SEACC::%s signatures are equal", __FUNCTION__);
+    return 0;
+  }
+  return 1;
+}
+
+int SElementArduinoCloudCertificate::rebuild(
+    SecureElement & se, ECP256Certificate & cert, const String & deviceId,
+    const String & notBefore, const String & notAfter, const String & serialNumber,
+    const String & authorityKeyIdentifier, const String & signature,
+    const SElementArduinoCloudSlot keySlot)
+{
+  byte serialNumberBytes[ECP256_CERT_SERIAL_NUMBER_LENGTH];
+  byte authorityKeyIdentifierBytes[ECP256_CERT_AUTHORITY_KEY_ID_LENGTH];
+  byte signatureBytes[ECP256_CERT_SIGNATURE_LENGTH];
+
+  if (!deviceId.length() || !notBefore.length() || !notAfter.length() || !serialNumber.length() || !authorityKeyIdentifier.length() || !signature.length() ) {
+    DEBUG_ERROR("SEACC::%s input params error.", __FUNCTION__);
+    return 0;
+  }
+
+  hexStringToBytes(serialNumber, serialNumberBytes, sizeof(serialNumberBytes));
+  hexStringToBytes(authorityKeyIdentifier, authorityKeyIdentifierBytes, sizeof(authorityKeyIdentifierBytes));
+  hexStringToBytes(signature, signatureBytes, sizeof(signatureBytes));
+
+  if (!cert.begin()) {
+    DEBUG_ERROR("SEACC::%s cert begin error", __FUNCTION__);
+    return -1;
+  }
+
+  cert.setSubjectCommonName(deviceId);
+  cert.setIssuerCountryName(SEACC_ISSUER_COUNTRY_NAME);
+  cert.setIssuerOrganizationName(SEACC_ISSUER_ORGANIZATION_NAME);
+  cert.setIssuerOrganizationalUnitName(SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME);
+  cert.setIssuerCommonName(SEACC_ISSUER_COMMON_NAME);
+  cert.setSignature(signatureBytes, sizeof(signatureBytes));
+  cert.setAuthorityKeyId(authorityKeyIdentifierBytes, sizeof(authorityKeyIdentifierBytes));
+  cert.setSerialNumber(serialNumberBytes, sizeof(serialNumberBytes));
+  cert.setIssueYear(notBefore.substring(0,4).toInt());
+  cert.setIssueMonth(notBefore.substring(5,7).toInt());
+  cert.setIssueDay(notBefore.substring(8,10).toInt());
+  cert.setIssueHour(notBefore.substring(11,13).toInt());
+  cert.setExpireYears(notAfter.substring(0,4).toInt() - notBefore.substring(0,4).toInt());
+
+
+  if (!SElementCertificate::build(se, cert, static_cast<int>(keySlot))) {
+    DEBUG_ERROR("SEACC::%s cert build error", __FUNCTION__);
+    return -1;
+  }
+  return 1;
+}
diff --git a/src/utility/SElementArduinoCloudCertificate.h b/src/utility/SElementArduinoCloudCertificate.h
index f6a1284..d20559a 100644
--- a/src/utility/SElementArduinoCloudCertificate.h
+++ b/src/utility/SElementArduinoCloudCertificate.h
@@ -28,6 +28,18 @@ class SElementArduinoCloudCertificate : public SElementCertificate
 
   static int write(SecureElement & se, ECP256Certificate & cert, const SElementArduinoCloudSlot certSlot);
   static int read(SecureElement & se, ECP256Certificate & cert, const SElementArduinoCloudSlot certSlot, const SElementArduinoCloudSlot keySlot = SElementArduinoCloudSlot::Key);
+  static int signatureCompare(const byte * signatureA, const String & signatureB);
+  static int rebuild(SecureElement & se, ECP256Certificate & cert, const String & deviceId,
+                    const String & notBefore, const String & notAfter, const String & serialNumber,
+                    const String & authorityKeyIdentifier, const String & signature,
+                    const SElementArduinoCloudSlot keySlot = SElementArduinoCloudSlot::Key);
+
+private:
+
+  static const char constexpr SEACC_ISSUER_COUNTRY_NAME[] = "US";
+  static const char constexpr SEACC_ISSUER_ORGANIZATION_NAME[] = "Arduino LLC US";
+  static const char constexpr SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME[] = "IT";
+  static const char constexpr SEACC_ISSUER_COMMON_NAME[] = "Arduino";
 
 };