diff --git a/config-templates/config.php b/config-templates/config.php
index d9fa2dde5f41815ebb7057652acb42d43df00e84..812e93985b4a04f4de85bb778fe4b789e539ba9f 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -382,6 +382,7 @@ $config = array (
 	 * if those aren't set, signing of metadata will fail.
 	 */
 	'metadata.sign.privatekey' => NULL,
+	'metadata.sign.privatekey_pass' => NULL,
 	'metadata.sign.certificate' => NULL,
 
 
diff --git a/docs/source/simplesamlphp-advancedfeatures.xml b/docs/source/simplesamlphp-advancedfeatures.xml
index 26bd79974cb8f2f63fc7617e2c3e5e5cd4678bdb..d8d2f74297b41844fcc0805156d2bf7d28c03511 100644
--- a/docs/source/simplesamlphp-advancedfeatures.xml
+++ b/docs/source/simplesamlphp-advancedfeatures.xml
@@ -369,7 +369,7 @@ foreach($_SERVER as $key=>$value) {
     <title>Metadata signing</title>
 
     <para>simpleSAMLphp supports signing of the metadata it generates.
-    Metadata signing is configured by three options:</para>
+    Metadata signing is configured by four options:</para>
 
     <itemizedlist>
       <listitem>
@@ -384,6 +384,13 @@ foreach($_SERVER as $key=&gt;$value) {
         file must exist in in the <literal>cert</literal> directory.</para>
       </listitem>
 
+      <listitem>
+        <para><literal>metadata.sign.privatekey_pass</literal>: Passphrase
+        which should be used to open the private key. This parameter is
+        optional, and should be left out if the private key is
+        unencrypted.</para>
+      </listitem>
+
       <listitem>
         <para><literal>metadata.sign.certificate</literal>: Name of the file
         with the certificate which matches the private key. This file must
@@ -400,9 +407,9 @@ foreach($_SERVER as $key=&gt;$value) {
     <para>There is also an additional fallback for the private key and the
     certificate. If <literal>metadata.sign.privatekey</literal> and
     <literal>metadata.sign.certificate</literal> isn't configured,
-    simpleSAMLphp will use the <literal>privatekey</literal> and
-    <literal>certificate</literal> options in the metadata for the
-    SP/IdP.</para>
+    simpleSAMLphp will use the <literal>privatekey</literal>,
+    <literal>privatekey_pass</literal> and <literal>certificate</literal>
+    options in the metadata for the SP/IdP.</para>
   </section>
 
 
diff --git a/docs/source/simplesamlphp-idp.xml b/docs/source/simplesamlphp-idp.xml
index 2469347cf5ab78449be0d1a2430b3040c3fa640a..689f26b4a4b5433f734d15797197b4da8382e226 100644
--- a/docs/source/simplesamlphp-idp.xml
+++ b/docs/source/simplesamlphp-idp.xml
@@ -401,6 +401,14 @@ openssl x509 -req -days 60 -in server2.csr -signkey server2.key -out server2.crt
         <title>Optional metadata fields</title>
 
         <glosslist>
+          <glossentry>
+            <glossterm>privatekey_pass</glossterm>
+
+            <glossdef>
+              <para>Passphrase for the private key.</para>
+            </glossdef>
+          </glossentry>
+
           <glossentry>
             <glossterm>requireconsent</glossterm>
 
diff --git a/docs/source/simplesamlphp-sp.xml b/docs/source/simplesamlphp-sp.xml
index f21449f92ece93c1c433d9eb15c80e405b2de81c..51d272805981951d039568bb7e2efb8b1c1f36ec 100644
--- a/docs/source/simplesamlphp-sp.xml
+++ b/docs/source/simplesamlphp-sp.xml
@@ -326,6 +326,15 @@
               generate SAML 2.0 Metadata for export to the IdP.</para>
             </glossdef>
           </glossentry>
+
+          <glossentry>
+            <glossterm>privatekey_pass</glossterm>
+
+            <glossdef>
+              <para>Optional field with the passphrase for the private
+              key.</para>
+            </glossdef>
+          </glossentry>
         </glosslist>
 
         <example>
@@ -560,6 +569,15 @@
               key.</para>
             </glossdef>
           </glossentry>
+
+          <glossentry>
+            <glossterm>privatekey_pass</glossterm>
+
+            <glossdef>
+              <para>Optional field with the passphrase for the private
+              key.</para>
+            </glossdef>
+          </glossentry>
         </glosslist>
 
         <example>
diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php b/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php
index 24f1bd8b3ee9c54c4af83cd2936104dc5a823e2e..ed9ee715abe5fed44df5d7914b830758fcfcfc1e 100644
--- a/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php
+++ b/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php
@@ -118,6 +118,13 @@ class SimpleSAML_Bindings_SAML20_HTTPPost {
 		/* create new XMLSecKey using RSA-SHA-1 and type is private key */
 		$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
 		
+		/* Set the passphrase which should be used to open the key, if this attribute is
+		 * set in the metadata.
+		 */
+		if(array_key_exists('privatekey_pass', $idpmd)) {
+			$objKey->passphrase = $idpmd['privatekey_pass'];
+		}
+
 		/* load the private key from file - last arg is bool if key in file (TRUE) or is string (FALSE) */
 		$objKey->loadKey($privatekey,TRUE);
 				
diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
index 52436bd3e554571f1951695d87ae8cf37d0ed76b..2bf82072d968bc651efb76dfd72140cc01a809bb 100644
--- a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
+++ b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
@@ -52,6 +52,14 @@ class SimpleSAML_Bindings_SAML20_HTTPRedirect {
 		$query = $query . "&" . "SigAlg=" . urlencode($algURI);
 		
 		$xmlseckey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
+
+		/* Set the passphrase which should be used to open the key, if this attribute is
+		 * set in the metadata.
+		 */
+		if(array_key_exists('privatekey_pass', $md)) {
+			$xmlseckey->passphrase = $md['privatekey_pass'];
+		}
+
 		$xmlseckey->loadKey($privatekey,TRUE);
         $signature = $xmlseckey->signData($query);
                 
diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
index 189a9ee3c975193e2dea6a77104677e6734eb63c..37adb633a7cba8d30a1091c248ea4f1f1950cc00 100644
--- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
+++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
@@ -118,9 +118,14 @@ class SimpleSAML_Bindings_Shib13_HTTPPost {
 
 		/* create new XMLSecKey using RSA-SHA-1 and type is private key */
 		$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
-		
-		//$objKey->passphrase = '1234';
-		
+
+		/* Set the passphrase which should be used to open the key, if this attribute is
+		 * set in the metadata.
+		 */
+		if(array_key_exists('privatekey_pass', $idpmd)) {
+			$objKey->passphrase = $idpmd['privatekey_pass'];
+		}
+
 		/* load the private key from file - last arg is bool if key in file (TRUE) or is string (FALSE) */
 		#$objKey->loadKey($privatekey_pem,false);
 		$objKey->loadKey($privatek,false);
diff --git a/lib/SimpleSAML/Metadata/Signer.php b/lib/SimpleSAML/Metadata/Signer.php
index eacf55cbec5484958af8697a99133b926061cc11..8d433aea0bb151bede58e9afbbbd0426198eb623 100644
--- a/lib/SimpleSAML/Metadata/Signer.php
+++ b/lib/SimpleSAML/Metadata/Signer.php
@@ -16,7 +16,7 @@ class SimpleSAML_Metadata_Signer {
 	 * @param $config  Our SimpleSAML_Configuration instance.
 	 * @param $entityMetadata  The metadata of the entity.
 	 * @param $type  A string which describes the type entity this is, e.g. 'SAML 2 IdP' or 'Shib 1.3 SP'.
-	 * @return An associative array with the keys 'privatekey' and 'certificate'.
+	 * @return An associative array with the keys 'privatekey', 'certificate', and optionally 'privatekey_pass'.
 	 */
 	private static function findKeyCert($config, $entityMetadata, $type) {
 
@@ -32,10 +32,17 @@ class SimpleSAML_Metadata_Signer {
 					' the ' . $type . ' "' . $entityMetadata['entityid'] . '". If one of' .
 					' these options is specified, then the other must also be specified.');
 			}
-			return array(
+
+			$ret = array(
 				'privatekey' => $entityMetadata['metadata.sign.privatekey'],
 				'certificate' => $entityMetadata['metadata.sign.certificate']
 				);
+
+			if(array_key_exists('metadata.sign.privatekey_pass', $entityMetadata)) {
+				$ret['privatekey_pass'] = $entityMetadata['metadata.sign.privatekey_pass'];
+			}
+
+			return $ret;
 		}
 
 		/* Then we look for default values in the global configuration. */
@@ -48,7 +55,14 @@ class SimpleSAML_Metadata_Signer {
 					' configuration. If one of these options is specified, then the other'.
 					' must also be specified.');
 			}
-			return array('privatekey' => $privatekey, 'certificate' => $certificate);
+			$ret = array('privatekey' => $privatekey, 'certificate' => $certificate);
+
+			$privatekey_pass = $config->getValue('metadata.sign.privatekey_pass', NULL);
+			if($privatekey_pass !== NULL) {
+				$ret['privatekey_pass'] = $privatekey_pass;
+			}
+
+			return $ret;
 		}
 
 		/* As a last resort we attempt to use the privatekey and certificate option from the metadata. */
@@ -63,11 +77,16 @@ class SimpleSAML_Metadata_Signer {
 					' from this entity.');
 			}
 
-			return array(
+			$ret = array(
 				'privatekey' => $entityMetadata['privatekey'],
 				'certificate' => $entityMetadata['certificate']
 				);
 
+			if(array_key_exists('privatekey_pass', $entityMetadata)) {
+				$ret['privatekey_pass'] = $entityMetadata['privatekey_pass'];
+			}
+
+			return $ret;
 		}
 
 		throw new Exception('Could not find what key & certificate should be used to sign the metadata' .
@@ -149,6 +168,9 @@ class SimpleSAML_Metadata_Signer {
 
 		/* Load the private key. */
 		$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
+		if(array_key_exists('privatekey_pass', $keyCertFiles)) {
+			$objKey->passphrase = $keyCertFiles['privatekey_pass'];
+		}
 		$objKey->loadKey($keyData, FALSE);
 
 		/* Get the EntityDescriptor node we should sign. */
diff --git a/www/admin/metadata.php b/www/admin/metadata.php
index 765f6174fa03da95406d0b4b98d4a36f4c6d2ead..ebf0972f07da2e514c1a9daded80d41e2c5b4593 100644
--- a/www/admin/metadata.php
+++ b/www/admin/metadata.php
@@ -29,7 +29,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host'),
-				array('request.signing','certificate','privatekey', 'NameIDFormat', 'ForceAuthn', 'AuthnContextClassRef', 'SPNameQualifier', 'attributemap', 'attributealter', 'attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.certificate')
+				array('request.signing','certificate','privatekey', 'privatekey_pass', 'NameIDFormat', 'ForceAuthn', 'AuthnContextClassRef', 'SPNameQualifier', 'attributemap', 'attributealter', 'attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate')
 			);
 		}
 		$et->data['metadata.saml20-sp-hosted'] = $results;
@@ -52,7 +52,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host', 'privatekey', 'certificate', 'auth'),
-				array('requireconsent','request.signing', 'authority', 'attributemap', 'attributealter', 'userid.attribute', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.certificate')
+				array('requireconsent','request.signing', 'privatekey_pass', 'authority', 'attributemap', 'attributealter', 'userid.attribute', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate')
 			);
 		}
 		$et->data['metadata.saml20-idp-hosted'] = $results;
@@ -89,7 +89,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'SingleSignOnService', 'certFingerprint'),
-				array('name', 'description', 'base64attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.certificate')
+				array('name', 'description', 'base64attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate')
 			);
 		}
 		$et->data['metadata.shib13-idp-remote'] = $results;
@@ -102,7 +102,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host', 'privatekey', 'certificate', 'auth'),
-				array('requireconsent', 'authority')
+				array('requireconsent', 'authority', 'privatekey_pass')
 			);
 		}
 		$et->data['metadata.shib13-idp-hosted'] = $results;
@@ -112,7 +112,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'AssertionConsumerService'),
-				array('base64attributes', 'audience', 'attributemap', 'attributealter', 'simplesaml.attributes', 'attributes', 'name', 'description', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.certificate')
+				array('base64attributes', 'audience', 'attributemap', 'attributealter', 'simplesaml.attributes', 'attributes', 'name', 'description', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate')
 			);
 		}
 		$et->data['metadata.shib13-sp-remote'] = $results;