How do I set different digest algorithm and signature algorithm for an idp in simplesamlphp - simplesamlphp

I am trying to set
DigestMethod Algorithm to
http://www.w3.org/2001/04/xmlenc#sha256
and SignatureMethod Algorithm to
http://www.w3.org/2000/09/xmldsig#rsa-sha1
I have set
'metadata.sign.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
and
'signature.algorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
I saw from a changelog that metadata.sign.algorithm was introduced as the digest algorithm. However both digest algorithm and signature algorithm seem to be taking from the value signature.algorithm. I am using SimpleSamlP v1.18.4.
Thanks in advance for your help.

The digest algorithm will be based on signature algorithm, at least this is so out of the box in simpleSAMLphp 1.18.4. If you set signature.algorithm to http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 you'll get http://www.w3.org/2001/04/xmlenc#sha256 as the digest algorithm. This is your best option.
In more detail:
The underlying XML Digital Signature spec does not say that the digest algorithm (DigestMethod element) has to depend on or be derived from the signing algorithm (SignatureMethod element). In practice, many XML Digital Signature libraries do base digest algorithm on signature algorithm as the default option. Some libraries allow these defaults to be manipulated, others do not. simpleSAMLphp uses XMLSecurityKey from xmlseclibs to compute signatures. Here's a constructor of XMLSecurityKey from xmlseclibs 3.0.4 that simpleSAMLphp 1.18.4 depends on:
case (self::RSA_SHA256):
$this->cryptParams['library'] = 'openssl';
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
$this->cryptParams['digest'] = 'SHA256';
if (is_array($params) && ! empty($params['type'])) {
if ($params['type'] == 'public' || $params['type'] == 'private') {
$this->cryptParams['type'] = $params['type'];
break;
}
}
As you can see, if it sees RSA-SHA256 as the signature algorithm, it sets the digest algorithm to SHA256. The digest/signature algorithms can be changed after construction but simpleSAMLphp doesn't go that far.
SAML has a profile that allows algorithms (including signature and digest) to be declared in metadata. The lower-level saml PHP library apparently supports this profile. You could give this a shot if you're not afraid of rolling your own implementation using this library.

I find https://github.com/simplesamlphp/simplesamlphp/blob/simplesamlphp-1.18/lib/SimpleSAML/Metadata/Signer.php use metadata.sign.algorithm for signing metadata and signature.algorithm used by https://github.com/simplesamlphp/simplesamlphp/blob/simplesamlphp-1.18/modules/saml/lib/Message.php to sign any messages from a Service Provider (SP).
Did you set all the related configuration for metadata.sign.algorithm in the configuration?
'metadata.sign.enable' => false,
'metadata.sign.privatekey' => null,
'metadata.sign.privatekey_pass' => null,
'metadata.sign.certificate' => null,
'metadata.sign.algorithm' => null,

It looks like SimpleSamlPHP does not allow this to be done. However I patched Utils.php inside SAML2 library to get this working
diff --git a/src/SAML2/Utils.php b/src/SAML2/Utils.php
index e894a3e..4894f84 100644
--- a/src/SAML2/Utils.php
+++ b/src/SAML2/Utils.php
## -339,6 +339,11 ## class Utils
$type = XMLSecurityDSig::SHA1;
}
+ // Patch to get SimpleSAMLPHP to return different
+ // algorithms for signature and digest
+ // to address Login.gov logout issue.
+ $type = XMLSecurityDSig::SHA256;
+
$objXMLSecDSig->addReferenceList(
[$root],
$type,
I set the signature algorithm to SHA1 in the config and applied this patch via composer to have digest use the SHA256 algorithm.

Related

Nodejs crypto: Elliptic Curve to sign message and export public key as text

I want to achieve the following with the Nodejs crypto module:
I want to sign a message with my private key on a defined EC and have the signature as raw buffer/hex.
I want to have the respective public key as raw buffer/hex.
I can achieve both goals individually, but I can not achieve them together currently and it seems strange, that this is so hard to achieve with the node crypto module.
With the following code it is easy to generate a signature on a curve, but I cannot manage to decode the publicKey:
//Get pub and priv key from curve
const {publicKey, privateKey} = crypto.generateKeyPairSync('ec', {'namedCurve' : 'secp128r1'});
var message = "Hello";
var signer = crypto.createSign('sha256');
signer.update(message);
// Signature as raw hex. That's what I want.
var sigString = signer.sign(privateKey, 'hex'); // Needs a proper KeyObject
And with this code it is easy to extract the public key for a private key from a curve but the key returned by curve.getPrivateKey is not allowed for signing:
refCurve = crypto.createECDH('secp128r1');
//Public key split into x and y components. That's what I want.
refPubKey = {
x: '0x' + curve.getPublicKey('hex').slice(2,34),
y: '0x' + curve.getPublicKey('hex').slice(-32)
}
It is not possible for me to achieve both at the same time. The problem is, that the curve object can ONLY export as buffer/hex, while all the signature functions in crypto ONLY accept proper KeyObjects. And at the same time it seems not possible to convert both into each other. The KeyObjects have no functionality to export to buffer and it is not possible to create a KeyObject from the raw key, exported from the curve. What am I missing? I was also trying to set the respective private Key on the curve with curve.setPrivateKey(privateKey) but even this does not work.
Alternatively, I would also be open to use another Node library, but those I found do not seem to support the curve that I want to use (SECP128R1)
For example, this is how easy it is with python and the ecdsa library:
sk = SigningKey.generate(curve=SECP128r1, hashfunc=sha256)
vk = sk.verifying_key
message = b"Hello"
m = sha256(message)
//Signature
signature = sk.sign(message)
//Public Key
[vk.to_string()[:16], vk.to_string()[16:]]
Thankful for any help!
You can export the public key with export() in X.509/SPKI format and DER encoded. For a secp128r1 key the last 32 bytes are the concatenation of x and y:
const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', { 'namedCurve': 'secp128r1' });
// ...
var key = publicKey.export({ type: 'spki', format: 'der' });
var rawX = key.subarray(-32, -16);
var rawY = key.subarray(-16);
console.log(key.toString('hex')); // e.g. 3036301006072a8648ce3d020106052b8104001c03220004d15885cfb3c75417bbeb95625da313dcb4d27ecb6f89923ae539faa7c09b4797
console.log(rawX.toString('hex')); // e.g. d15885cfb3c75417bbeb95625da313dc
console.log(rawY.toString('hex')); // e.g. b4d27ecb6f89923ae539faa7c09b4797
This can be checked in an ASN.1 parser, e.g. https://lapo.it/asn1js/.
Note that this curve should not be used because of its length according to NIST.
Another convenient option is the export as JWK, because here x and y can be extracted directly (Base64url encoded). However, only the curves supported by JWK can be exported this way, secp128r1 is not one of them.

Generate RSA key-pair from "N", "E", "D" keys using crypto module

i'm new to cryptography.
I'm creating the RSA key-pairs using crypto.generateKeyPairSync()
const crypto = require('crypto')
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicExponent: 3,
publicKeyEncoding: {
type: 'pkcs1',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs1',
format: 'pem'
}
})
console.log(publicKey)
console.log(privateKey)
// print "n", "e", "d" keys
This works fine but the i need to extract the "n", "e", "d" keys so that an other app can encrypt and decrypt the messages. It would be great if this is possible without any 3rd-party libraries only the native NodeJS crypto module.
Also if it's not possible to extract the "n", "e", "d" keys, would it be possible to create a new public and private key using existing "n", "e", "d" keys from an other app?
This works fine but the i need to extract the "n", "e", "d" keys so that an other app can encrypt and decrypt the messages. It would be great if this is possible without any 3rd-party libraries only the native NodeJS crypto module.
First of all, the modulus n, public exponent e and private exponent d are not keys, they are components that are used to make up a key. As an RSA key contains at least two components you need some kind of method to distinguish them from each other. You need some kind of data structure which separates the components, which is exactly what the PKCS#1 ASN.1 specifications provide. Just specifying that you will deliver an RSA key using a PEM formatted PKCS#1 should be enough.
The private key, as the name suggests, should really not be shared. There is no such thing as a shared private key after all. Keys are generated for one specific entity, and are usually kept where they are generated (possibly exempting encrypted backup).
If you use only n and d then you will probably leave out any generated CRT parameters for the private key, which means that in the best case the RSA key operations don't run. In the worst case the RSA implementation is extremely picky and won't run at all.
Finally, as the documentation correctly indicates, you should be using 'spki' as output format (the public key as used within certificates, called the SubjectPublicKeyIdentifier, specified in the X.509 standards) and 'pkcs8' as they contain an indication of the key type used. These are probably better supported by other applications than PKCS#1.
If they are not able to decode it themselves then simply copy the base 64 into this site (online ASN.1 decoder) and copy the relevant values. You can find the order of the values (for 'pkcs1') in the PKCS#1 standard.
You could use the library pem-jwk to extract the components of the public/private keys like this:
const pem2jwk = require('pem-jwk').pem2jwk
console.log(pem2jwk(pemPublicKey));
OUTPUT:
{
kty: '...',
n: '...',
e: '...'
}
console.log(pem2jwk(pemPrivateKey));
OUTPUT:
{
kty: '...',
n: '...',
e: '...',
d: '...',
p: '...',
q: '...',
dp: '...',
dq: '...',
qi: '...'
}

Puppet: configuring with augeas a set of [keys:values] via create_resources from hiera

I am trying to create an interface to pseudo-loop over a set of keys:values from my hiera yaml to update a config file with augeas
define augeas_config (
$key,
$value
)
{
augeas{ "/var/MYCONF/MYCONF.def":
lens => "/var/lib/puppet/lib/augeas/lenses/MYCONF.aug",
incl => "/var/MYCONF/MYCONF.def",
context => "/var/MYCONF/MYCONF.def",
changes => [ "set $key $val" ],
}
}
$augeas_files = hiera_hash('lib_BOX::MYCONF::config', {} )
validate_hash($augeas_files)
create_resources('augeas_config', $augeas_files)
where in my yaml keys:values to be updated are supposed to be in a hash like
lib_BOX::MYCONF::config:
SITE_NAME: "TEST-SITE"
OTHER_STUFF: "DEBUG"
So, the idea is to apply my augeas lense (not sure, if I really need 'context', when 'incl' has to be used with 'lens') for the pairs from my yaml.
However, puppet fails currently complaining about a string instead of an expected hash
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Evaluation Error: Error while evaluating a Function Call, can't convert String into Hash at /etc/puppet/environments/development/modules/lib_BOX/manifests/config.pp:28:3 on node MY.NODE.FOO
where line 28 is the one with "create_resources('augeas_config'...". Since I get a hash from hiera, I suppose something in my resource definition is broken, but I do not see what??
Maybe somebody has an idea for me?
Cheers and thanks,
Thomas
Data in your yaml file is invalid. Change it to something like:
lib_BOX::MYCONF::config:
first_aug:
key: SITE_NAME
value: "TEST-SITE"
second_aug:
key: OTHER_STUFF
value : "DEBUG"
In addition you do not have to use hiera_hash. You can use just hiera.
Please read about differences between hiera lookup functions and follow examples about lookup types.
Probably you will also have to remove line validate_hash($augeas_files).

How I can reference a field defined in the gradle script?

I have a script to prepare build of an apk.
It defines some value which has some random specific for each build value:
def salt = generateSalt()
def generatedSalt() {
return generateRandomlySalt
}
In the same script I want to have another method which will operate on this value.
def generateMapAndSalt() {
// here is additional logic which depends on the defined salt
generateEncodedHash(certificate, salt, shaKey)
}
There is another method inside of android closure which will pass this defined salt value to the buildConfigFiles.
How do I reference once generated salt value from defined method?
Tired accessing it with following syntax:
this.$salt
$salt
salt
With no luck.
You can define the salt in an ext block and refer to it via project instance.
ext {
salt = generateSalt()
}
project.salt

understanding repl in puppet code

I am looking at puppet code that looks something like
class {
users => {
'repl#%' => {
ensure => present,
.
}
}
}
What does "repl" do? I cant find much information online.
The amount of anonymization almost hides the important points. But I belive that this is supposed to be the declaration of a hash, meant for use with the create_resources function.
It works like this: If you have a large number of resources that should not take all the space in your class (this reason is contrived), you can convert it to a hash structure instead.
mysql_grant {
'repl#%':
ensure => present,
rights => 'REPLICATION CLIENT';
}
This becomes a hash, stored in a variable.
$users = {
'repl#%' => {
ensure => present,
rights => 'REPLICATION CLIENT',
}
}
This can then be used to declare this (and more resources in the hash, if there is more than one) in a simple line.
create_resources('mysql_grant', $users)
I'm guessing that you are looking at grants because repl#% is a typical MySQL notation that means user with name "repl" from any client.
TL;DR it is a domain specific identifier and has no special meaning to Puppet itself.

Resources