diff --git a/src/knot/dnssec/zone-keys.c b/src/knot/dnssec/zone-keys.c
index 500724213d552847497fa28d1fc6cfd93c991151..9297a521a896189e654e8c6a08e38df360ddc69b 100644
--- a/src/knot/dnssec/zone-keys.c
+++ b/src/knot/dnssec/zone-keys.c
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -25,6 +25,9 @@
 #include "knot/dnssec/zone-keys.h"
 #include "libknot/libknot.h"
 #include "libknot/rrtype/dnskey.h"
+#include "contrib/dynarray.h"
+
+dynarray_define(keyptr, zone_key_t *, 1)
 
 /*!
  * \brief Get key feature flags from key parameters.
@@ -319,22 +322,20 @@ void free_zone_keys(zone_keyset_t *keyset)
 }
 
 /*!
- * \brief Get zone key by a keytag.
+ * \brief Get zone keys by keytag.
  */
-const zone_key_t *get_zone_key(const zone_keyset_t *keyset, uint16_t search)
+struct keyptr_dynarray get_zone_keys(const zone_keyset_t *keyset, uint16_t search)
 {
-	if (!keyset) {
-		return NULL;
-	}
+	struct keyptr_dynarray res = { 0 };
 
-	for (size_t i = 0; i < keyset->count; i++) {
+	for (size_t i = 0; keyset && i < keyset->count; i++) {
 		zone_key_t *key = &keyset->keys[i];
-		if (dnssec_key_get_keytag(key->key) == search) {
-			return key;
+		if (key != NULL && dnssec_key_get_keytag(key->key) == search) {
+			keyptr_dynarray_add(&res, &key);
 		}
 	}
 
-	return NULL;
+	return res;
 }
 
 /*!
diff --git a/src/knot/dnssec/zone-keys.h b/src/knot/dnssec/zone-keys.h
index dc0dd61fc53c2153eaaf7379c4adccd47c2e9146..5e306b69e098512a6930f97e69b17683331d6216 100644
--- a/src/knot/dnssec/zone-keys.h
+++ b/src/knot/dnssec/zone-keys.h
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -72,14 +72,14 @@ int load_zone_keys(dnssec_kasp_zone_t *zone, dnssec_keystore_t *store,
                    bool nsec3_enabled, time_t now, zone_keyset_t *keyset_ptr);
 
 /*!
- * \brief Get zone key by a keytag.
+ * \brief Get zone keys by a keytag.
  *
- * \param keys    Zone keys.
- * \param keytag  Keytag to lookup a key for.
+ * \param keyset  Zone keyset.
+ * \param search  Keytag to lookup a key for.
  *
- * \return Pointer to key or NULL if not found.
+ * \return Dynarray of pointers to keys.
  */
-const zone_key_t *get_zone_key(const zone_keyset_t *keyset, uint16_t keytag);
+struct keyptr_dynarray get_zone_keys(const zone_keyset_t *keyset, uint16_t search);
 
 /*!
  * \brief Free structure with zone keys and associated DNSSEC contexts.
diff --git a/src/knot/dnssec/zone-sign.c b/src/knot/dnssec/zone-sign.c
index 0f79051ab09a21bcccd8d80c6f4f038bc1444d1a..16f548ced052770855f9566a9215db49b6e4181b 100644
--- a/src/knot/dnssec/zone-sign.c
+++ b/src/knot/dnssec/zone-sign.c
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -35,8 +35,11 @@
 #include "libknot/rrset.h"
 #include "libknot/rrtype/rrsig.h"
 #include "libknot/rrtype/soa.h"
+#include "contrib/dynarray.h"
 #include "contrib/macros.h"
 
+dynarray_define(keyptr, zone_key_t *, 1)
+
 typedef struct type_node {
 	node_t n;
 	uint16_t type;
@@ -110,8 +113,10 @@ static bool valid_signature_exists(const knot_rrset_t *covered,
 			continue;
 		}
 
-		return knot_check_signature(covered, rrsigs, i, key, ctx,
-		                            dnssec_ctx) == KNOT_EOK;
+		if (knot_check_signature(covered, rrsigs, i, key, ctx,
+		                         dnssec_ctx) == KNOT_EOK) {
+			return true;
+		}
 	}
 
 	return false;
@@ -182,18 +187,17 @@ static bool all_signatures_exist(const knot_rrset_t *covered,
  * \param pos     Number of RR in RR set.
  * \param keys    Zone keys.
  *
- * \return Zone key or NULL if a that key does not exist.
+ * \return Dynarray of such keys.
  */
-static const zone_key_t *get_matching_zone_key(const knot_rrset_t *rrsigs,
-                                               size_t pos,
-                                               const zone_keyset_t *keys)
+static struct keyptr_dynarray get_matching_zone_keys(const knot_rrset_t *rrsigs,
+                                                     size_t pos, const zone_keyset_t *keys)
 {
 	assert(rrsigs && rrsigs->type == KNOT_RRTYPE_RRSIG);
 	assert(keys);
 
 	uint16_t keytag = knot_rrsig_key_tag(&rrsigs->rrs, pos);
 
-	return get_zone_key(keys, keytag);
+	return get_zone_keys(keys, keytag);
 }
 
 /*!
@@ -257,21 +261,30 @@ static int remove_expired_rrsigs(const knot_rrset_t *covered,
 
 	uint16_t rrsig_rdata_count = synth_rrsig.rrs.rr_count;
 	for (uint16_t i = 0; i < rrsig_rdata_count; i++) {
-		const zone_key_t *key;
-		key = get_matching_zone_key(&synth_rrsig, i, zone_keys);
+		struct keyptr_dynarray keys = get_matching_zone_keys(&synth_rrsig, i, zone_keys);
+		keyptr_dynarray_fix(&keys);
+		int endloop = 0; // 1 - continue; 2 - break
 
-		if (key && key->is_active) {
+		for (size_t j = 0; j < keys.size && endloop == 0; j++) {
+			if (!keys.arr[j]->is_active) {
+				continue;
+			}
 			result = knot_check_signature(covered, &synth_rrsig, i,
-			                         key->key, key->ctx, dnssec_ctx);
+			                              keys.arr[j]->key, keys.arr[j]->ctx, dnssec_ctx);
 			if (result == KNOT_EOK) {
 				// valid signature
 				note_earliest_expiration(&synth_rrsig, i, expires_at);
-				continue;
+				endloop = 1;
+			} else if (result != DNSSEC_INVALID_SIGNATURE) {
+				endloop = 2;
 			}
+		}
+		keyptr_dynarray_free(&keys);
 
-			if (result != DNSSEC_INVALID_SIGNATURE) {
-				break;
-			}
+		if (endloop == 2) {
+			break;
+		} else if (endloop == 1) {
+			continue;
 		}
 
 		if (knot_rrset_empty(&to_remove)) {
@@ -643,9 +656,20 @@ static bool dnskey_in_keyset(const zone_keyset_t *keyset,
 
 	uint16_t tag = 0;
 	dnssec_keytag(&rdata, &tag);
-	const zone_key_t *key = get_zone_key(keyset, tag);
+	bool found = false;
+
+	struct keyptr_dynarray keys = get_zone_keys(keyset, tag);
+	keyptr_dynarray_fix(&keys);
+
+	for (size_t i = 0; i < keys.size; i++) {
+		if (keys.arr[i]->is_public && dnskey_rdata_match(keys.arr[i], &rdata)) {
+			found = true;
+			break;
+		}
+	}
+	keyptr_dynarray_free(&keys);
 
-	return (key && key->is_public && dnskey_rdata_match(key, &rdata));
+	return found;
 }
 
 /*!