diff --git a/lib/SAML2/HTTPRedirect.php b/lib/SAML2/HTTPRedirect.php
index 6b001de18455c56caafb54e2d67141a73d46094a..6033389a070c29071a7fa690dead967af3fc78af 100644
--- a/lib/SAML2/HTTPRedirect.php
+++ b/lib/SAML2/HTTPRedirect.php
@@ -51,7 +51,7 @@ class SAML2_HTTPRedirect extends SAML2_Binding {
 
 		if ($key !== NULL) {
 			/* Add the signature. */
-			$msg .= '&SigAlg=' . urlencode(XMLSecurityKey::RSA_SHA1);
+			$msg .= '&SigAlg=' . urlencode($key->type);
 
 			$signature = $key->signData($msg);
 			$msg .= '&Signature=' . urlencode(base64_encode($signature));
@@ -216,17 +216,15 @@ class SAML2_HTTPRedirect extends SAML2_Binding {
 
 		$signature = base64_decode($signature);
 
-		switch ($sigAlg) {
-		case XMLSecurityKey::RSA_SHA1:
-			if ($key->type !== XMLSecurityKey::RSA_SHA1) {
-				throw new Exception('Invalid key type for validating signature on query string.');
-			}
-			if (!$key->verifySignature($query,$signature)) {
-				throw new Exception('Unable to validate signature on query string.');
-			}
-			break;
-		default:
-			throw new Exception('Unknown signature algorithm: ' . var_export($sigAlg, TRUE));
+		if ($key->type !== XMLSecurityKey::RSA_SHA1) {
+			throw new Exception('Invalid key type for validating signature on query string.');
+		}
+		if ($key->type !== $sigAlg) {
+			$key = SAML2_Utils::castKey($key, $sigAlg);
+		}
+
+		if (!$key->verifySignature($query,$signature)) {
+			throw new Exception('Unable to validate signature on query string.');
 		}
 	}
 
diff --git a/lib/SAML2/Utils.php b/lib/SAML2/Utils.php
index 79576a2b6b998ad756ad3e454d10303e541cf6c4..5120639cc9a57159ef1de7d65daa5af823691b12 100644
--- a/lib/SAML2/Utils.php
+++ b/lib/SAML2/Utils.php
@@ -91,10 +91,17 @@ class SAML2_Utils {
 	 *
 	 * @param XMLSecurityKey $key  The key.
 	 * @param string $algorithm  The desired algorithm.
+	 * @param string $types  Public or private key, defaults to public.
 	 * @return XMLSecurityKey  The new key.
 	 */
-	private static function castKey(XMLSecurityKey $key, $algorithm) {
+	public static function castKey(XMLSecurityKey $key, $algorithm, $type = 'public') {
 		assert('is_string($algorithm)');
+		assert('$type === "public" || $type === "private"');
+
+		// do nothing if algorithm is already the type of the key
+		if ($key->type === $algorithm) {
+			return $key;
+		}
 
 		$keyInfo = openssl_pkey_get_details($key->key);
 		if ($keyInfo === FALSE) {
@@ -104,7 +111,7 @@ class SAML2_Utils {
 			throw new Exception('Missing key in public key details.');
 		}
 
-		$newKey = new XMLSecurityKey($algorithm, array('type'=>'public'));
+		$newKey = new XMLSecurityKey($algorithm, array('type'=>$type));
 		$newKey->loadKey($keyInfo['key']);
 		return $newKey;
 	}
@@ -133,18 +140,8 @@ class SAML2_Utils {
 		}
 		$algo = $sigMethod->getAttribute('Algorithm');
 
-		if ($key->type === XMLSecurityKey::RSA_SHA1) {
-			switch ($algo) {
-				case XMLSecurityKey::RSA_SHA256:
-					$key = self::castKey($key, XMLSecurityKey::RSA_SHA256);
-					break;
-				case XMLSecurityKey::RSA_SHA384:
-					$key = self::castKey($key, XMLSecurityKey::RSA_SHA384);
-					break;
-				case XMLSecurityKey::RSA_SHA512:
-					$key = self::castKey($key, XMLSecurityKey::RSA_SHA512);
-					break;
-			}
+		if ($key->type === XMLSecurityKey::RSA_SHA1 && $algo !== $key->type) {
+			$key = self::castKey($key, $algo);
 		}
 
 		/* Check the signature. */
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 6e90d65ce5ccf11761b3e37aee72869c1f39cb20..64c06da132b4848b3a3e29b4db2d0cae673ebeef 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -21,7 +21,11 @@ class sspmod_saml_Message {
 
 		$keyArray = SimpleSAML_Utilities::loadPrivateKey($srcMetadata, TRUE);
 		$certArray = SimpleSAML_Utilities::loadPublicKey($srcMetadata, FALSE);
-		$algo = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA1);
+
+		$algo = $dstMetadata->getString('signature.algorithm', NULL);
+		if ($algo === NULL) {
+			$algo = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA1);
+		}
 
 		$privateKey = new XMLSecurityKey($algo, array('type' => 'private'));
 		if (array_key_exists('password', $keyArray)) {