Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce more secure XML encryption #584

Merged
merged 1 commit into from May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/node-saml/saml.ts
Expand Up @@ -1352,9 +1352,10 @@ class SAML {
},
EncryptionMethod: [
// this should be the set that the xmlenc library supports
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#aes256-gcm" },
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#aes128-gcm" },
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#aes256-cbc" },
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#aes128-cbc" },
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#tripledes-cbc" },
],
});
}
Expand Down
4 changes: 2 additions & 2 deletions test/node-saml/tests.spec.ts
Expand Up @@ -1844,7 +1844,7 @@ describe("node-saml /", function () {
};
const { profile } = await samlObj.validatePostRequestAsync(body);
profile!.should.eql({
ID: "pfx00cb5227-d9d0-1d4b-bdb2-c7ad6c3c6906",
ID: "pfx087316a5-2dfb-cc05-2ba9-b46751936ff5",
issuer: "http://sp.example.com/demo1/metadata.php",
nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7",
nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
Expand All @@ -1864,7 +1864,7 @@ describe("node-saml /", function () {
),
};
await assert.rejects(samlObj.validatePostRequestAsync(body), {
message: "Encryption block is invalid.",
message: "Invalid RSAES-OAEP padding.",
});
});

Expand Down
137 changes: 137 additions & 0 deletions test/node-saml/xml.spec.ts
@@ -0,0 +1,137 @@
"use strict";
import * as xmlenc from "xml-encryption";
import * as fs from "fs";
import * as util from "util";
import * as should from "should";
import assert = require("assert");

export const encrytpXml = util.promisify(xmlenc.encrypt);
export const decryptXml = util.promisify(xmlenc.decrypt);

describe("xml /", async function () {
const rsa_pub = fs.readFileSync(__dirname + "/../static/testshib encryption pub.pem");
const pem = fs.readFileSync(__dirname + "/../static/testshib encryption cert.pem");
const key = fs.readFileSync(__dirname + "/../static/testshib encryption pvk.pem");

it("should decrypt aes128-cbc/rsa-oaep-mgf1p", async function () {
const encryptOptions: xmlenc.EncryptOptions = {
rsa_pub,
pem,
encryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#aes128-cbc",
keyEncryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
};

const decryptOptions: xmlenc.DecryptOptions = {
key,
disallowDecryptionWithInsecureAlgorithm: true,
};

const originalPayload = "XML payload";
const encryptedPayload = await encrytpXml(originalPayload, encryptOptions);
const decryptedPayload = await decryptXml(encryptedPayload, decryptOptions);

should(originalPayload).equal(decryptedPayload);
});

it("should decrypt aes256-cbc/rsa-oaep-mgf1p", async function () {
const encryptOptions: xmlenc.EncryptOptions = {
rsa_pub,
pem,
encryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#aes256-cbc",
keyEncryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
};

const decryptOptions: xmlenc.DecryptOptions = {
key,
disallowDecryptionWithInsecureAlgorithm: true,
};

const originalPayload = "XML payload";
const encryptedPayload = await encrytpXml(originalPayload, encryptOptions);
const decryptedPayload = await decryptXml(encryptedPayload, decryptOptions);

should(originalPayload).equal(decryptedPayload);
});

it("should decrypt aes128-gcm/rsa-oaep-mgf1p", async function () {
const encryptOptions: xmlenc.EncryptOptions = {
rsa_pub,
pem,
encryptionAlgorithm: "http://www.w3.org/2009/xmlenc11#aes128-gcm",
keyEncryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
};

const decryptOptions: xmlenc.DecryptOptions = {
key,
disallowDecryptionWithInsecureAlgorithm: true,
};

const originalPayload = "XML payload";
const encryptedPayload = await encrytpXml(originalPayload, encryptOptions);
const decryptedPayload = await decryptXml(encryptedPayload, decryptOptions);

should(originalPayload).equal(decryptedPayload);
});

it("should decrypt aes256-gcm/rsa-oaep-mgf1p", async function () {
const encryptOptions: xmlenc.EncryptOptions = {
rsa_pub,
pem,
encryptionAlgorithm: "http://www.w3.org/2009/xmlenc11#aes256-gcm",
keyEncryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
};

const decryptOptions: xmlenc.DecryptOptions = {
key,
disallowDecryptionWithInsecureAlgorithm: true,
};

const originalPayload = "XML payload";
const encryptedPayload = await encrytpXml(originalPayload, encryptOptions);
const decryptedPayload = await decryptXml(encryptedPayload, decryptOptions);

should(originalPayload).equal(decryptedPayload);
});

it("should not decrypt tripledes-cbc/rsa-oaep-mgf1p", async function () {
const encryptOptions: xmlenc.EncryptOptions = {
rsa_pub,
pem,
encryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#tripledes-cbc",
keyEncryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
warnInsecureAlgorithm: false,
};

const decryptOptions: xmlenc.DecryptOptions = {
key,
disallowDecryptionWithInsecureAlgorithm: true,
};

const originalPayload = "XML payload";
const encryptedPayload = await encrytpXml(originalPayload, encryptOptions);
const decryptedPayload = await assert.rejects(decryptXml(encryptedPayload, decryptOptions));

should(decryptedPayload).be.undefined();
});

it("should not decrypt aes256-gcm/rsa-1_5", async function () {
const encryptOptions: xmlenc.EncryptOptions = {
rsa_pub,
pem,
encryptionAlgorithm: "http://www.w3.org/2009/xmlenc11#aes256-gcm",
keyEncryptionAlgorithm: "http://www.w3.org/2001/04/xmlenc#rsa-1_5",
warnInsecureAlgorithm: false,
};

const decryptOptions: xmlenc.DecryptOptions = {
key,
disallowDecryptionWithInsecureAlgorithm: true,
};

const originalPayload = "XML payload";
const encryptedPayload = await encrytpXml(originalPayload, encryptOptions);
const decryptedPayload = await assert.rejects(decryptXml(encryptedPayload, decryptOptions));

should(decryptedPayload).be.undefined();
});
});
3 changes: 2 additions & 1 deletion test/static/expected metadata.xml
Expand Up @@ -33,9 +33,10 @@ nwtlCg==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-gcm"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-gcm"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
</KeyDescriptor>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<AssertionConsumerService index="1" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://example.serviceprovider.com/saml/callback"/>
Expand Down
3 changes: 2 additions & 1 deletion test/static/expectedMetadataWithBothKeys.xml
Expand Up @@ -55,9 +55,10 @@ nwtlCg==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-gcm"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-gcm"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
</KeyDescriptor>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<AssertionConsumerService index="1" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://example.serviceprovider.com/saml/callback"/>
Expand Down
40 changes: 20 additions & 20 deletions test/static/logout_request_with_encrypted_name_id.xml
@@ -1,25 +1,25 @@
<?xml version="1.0"?>
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfx00cb5227-d9d0-1d4b-bdb2-c7ad6c3c6906" Version="2.0" IssueInstant="2014-07-18T01:13:06Z" Destination="http://idp.example.com/SingleLogoutService.php">
<saml:Issuer>http://sp.example.com/demo1/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfx087316a5-2dfb-cc05-2ba9-b46751936ff5" Version="2.0" IssueInstant="2014-07-18T01:13:06Z" Destination="http://idp.example.com/SingleLogoutService.php">
<saml:Issuer>http://sp.example.com/demo1/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#pfx00cb5227-d9d0-1d4b-bdb2-c7ad6c3c6906"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>myTkSwwgK+Lcx5JZukoHggbFBVA=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>ayMUV7pPijoh7ocMnIz2GPYK7Y4Olib+U1mIUX0o7uU22m+ZGUP2HkmvC7bIZ4N3MFyeUyPuEBTDdFtLaENTWzovGMNRXDSypNI5UwobGqAFu16BY9lL5uJ/6HAAEgayxaY5kVMEY4VmNUpNCIE0WMpzA91bnElbEFsxi6G8sUj49oDFYncbOHilThLoe0dPQxB7N1wfX73k5nZ/hkEPlbwvENJRRojvwlbcn7crviYRzbzJPa31iMKmaSTaoS7cIV0Q8V1jYuQV29Y4eNwbVa4ZGu06by5CFXHYZoev0zyEoOTCNgQuF72zxzOmzDF5yEH5fWPE0QwUhf8MMGOtGg==</ds:SignatureValue>
<ds:Reference URI="#pfx087316a5-2dfb-cc05-2ba9-b46751936ff5"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>TZyaJFBL1nzPZ0Rfo5Uf6M7djik=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>q7vWdkkgha/k4gLewZ67Yky4sNZXA0HH787fgKlCW0JSdlbxsEtQeqx1TJgCdONFMV1kmwgmqEpW8etqXbL2k2HygJS/QzE9Jmonw1PaLDNoEYyh2UVFl2JZgEr762Z3RgxxWhbxND1V5WQV/amw1zgd30FL3FPr+PYxkqXZtk2cuVFrkMN6axURbZZrazX4uj9TeBvi/SQNDuDXmBstJHWxR93oMZzelBJMlxY7XINLdL5NVu8uTENtVKZX3vLvhR4STLlTSsDO9QYfNoBc6d7rbjJziLDR6YGB6KGMTEUnApi7zgzckUgOojXl7Ql2wwfyrprsJ/RsGk24R1+cug==</ds:SignatureValue>
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDtTCCAp2gAwIBAgIJAKg4VeVcIDz1MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTUwODEzMDE1NDIwWhcNMTUwOTEyMDE1NDIwWjBFMQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxG3ouM7U+fXbJt69X1H6d4UNg/uRr06pFuU9RkfIwNC+yaXyptqB3ynXKsL7BFt4DCd0fflRvJAx3feJIDp16wN9GDVHcufWMYPhh2j5HcTW/j9JoIJzGhJyvO00YKBt+hHy83iN1SdChKv5y0iSyiPP5GnqFw+ayyHoM6hSO0PqBou1Xb0ZSIE+DHosBnvVna5w2AiPY4xrJl9yZHZ4Q7DfMiYTgstjETio4bX+6oLiBnYktn7DjdEslqhffVme4PuBxNojI+uCeg/sn4QVLd/iogMJfDWNuLD8326Mi/FE9cCRvFlvAiMSaebMI3zPaySsxTK7Zgj5TpEbmbHI9wIDAQABo4GnMIGkMB0GA1UdDgQWBBSVGgvoW4MhMuzBGce29PY8vSzHFzB1BgNVHSMEbjBsgBSVGgvoW4MhMuzBGce29PY8vSzHF6FJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAKg4VeVcIDz1MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJu1rqs+anD74dbdwgd3CnqnQsQDJiEXmBhG2leaGt3ve9b/9gKaJg2pyb2NyppDe1uLqh6nNXDuzg1oNZrPz5pJL/eCXPl7FhxhMUi04TtLf8LeNTCIWYZiFuO4pmhohHcv8kRvYR1+6SkLTC8j/TZerm7qvesSiTQFNapa1eNdVQ8nFwVkEtWl+JzKEM1BlRcn42sjJkijeFp7DpI7pU+PnYeiaXpRv5pJo8ogM1iFxN+SnfEs0EuQ7fhKIG9aHKi7bKZ7L6SyX7MDIGLeulEU6lf5D9BfXNmcMambiS0pXhL2QXajt96UBq8FT2KNXY8XNtR4y6MyyCzhaiZZcc8=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature>
<saml:EncryptedID>
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedKey>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<xenc:CipherData>
<xenc:CipherValue>Rtg5L09Un3DdhYBFJvYp4w1WGKHIi0Umf9PaFdiSL2r+1NK+Z76NwhR4vsIu1lq2BJEX1ZMTEJ/kitF/PgEqeAOGyLu80dmXyNbhKwbEZrbv+dYx5vJ21nHIbLeeknNB70XsGFtcrWbCqt2r6/e5wFxD7HglPmxWEzNgz5SGEki35MWqtCbfX8lTCsnKFEKU9GfaHYIfPZzf/szwJZVGJps5HI/k7wuKbfS/U8odxsyWX73//+rkduhF9j5Iq95+xd1KRrxcuyvfYsXH5SWcnXt2nIlHWuCDHVNILoWDvskvOyGTP1e+8K+W2sgptoA98D6NJb+k+x/TCD1eFbce5w==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
</dsig:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>hbSadp3tEX/QyaTsIpChQQat89Yc3shCc6728DoS4qzdrsswHIUoBjp5hKDjlECJBQvXSNFV3vYn93pm44/fl0Z3yTqKkt6eUI3lZQ3ZsVfzVwkNT2jAnZom+OThhVfb1vcpN62tDmGI2dLxzZAvOuvmuG52qambAnZ6hR4FevVyCww5AkD86x8Q8OWYUTwPsggDOuQEbDyMXG4YoRpUag9boTMoUcidmUQaeO6omLzr/Mg1P0xY8fkVetVh63L1T6Kp+6c17bSIW1q4e8SazujVoQZ5eCJP4DQHAvmmcEs=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</saml:EncryptedID>
<samlp:SessionIndex>1</samlp:SessionIndex>
<EncryptedID>
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedKey>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<xenc:CipherData>
<xenc:CipherValue>bDnwEZFatLVCzoioybJCGEATgse6O9UfhsJ2zriOBd+IPND1iBopwmZpJk5e0zYQq7VkiKLhhxCcRmLUyNrljMWSZIafqHNkwOttpay0OfKdlZ2Ecj1hHOIE8tjkGU4mtuyKr6XnLN8fbfpP57HhYye/Yj4sUtEMwEKAxotYej5GKDXzLUCKVg7ex/CB5gc+h+cBCgiUhY3xUL3xFeoc6LwHwt05e/v1MMXKx2yuSmccokjWXHchwyjKoijcxZwLkQUmRUDj+kY57LrqIqbkVLXtXi3LIcZHHM42K9oZr31kOUIOmEackU59Z/ubGGpFWammMlGEBnnbbhmXwwYd4g==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
</dsig:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>utUjNNsfoMg7loM/8g7DmohZwLl9a8ijQtJHhZ7SpvOHbkaZQkyOvv7zAopNm2WahxAXV38OSL0C0hWnr3P+D7B3MuGc/4RJhPdl/rRaUAlgloRqtH3UDyt79pRRJPGZzGTkIuGbp69sK+jiRShsRDGZ3YsaIppbP4/A5IxuTiM0ykzQ8Vv4nXpZ4MPbIwj3I+PzFF/XCOL9JXWW9U3Ne41FM3twQlytqxG7Sx7eYSf6w09Lbl411EsGDjusNdQzpzf5ydbQHCXdgS6FaRg1y59F40XkaGMXgSvK5GaB090=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</EncryptedID>
<samlp:SessionIndex>1</samlp:SessionIndex>
</samlp:LogoutRequest>
9 changes: 9 additions & 0 deletions test/static/pub.pem
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxG3ouM7U+fXbJt69X1H6
d4UNg/uRr06pFuU9RkfIwNC+yaXyptqB3ynXKsL7BFt4DCd0fflRvJAx3feJIDp1
6wN9GDVHcufWMYPhh2j5HcTW/j9JoIJzGhJyvO00YKBt+hHy83iN1SdChKv5y0iS
yiPP5GnqFw+ayyHoM6hSO0PqBou1Xb0ZSIE+DHosBnvVna5w2AiPY4xrJl9yZHZ4
Q7DfMiYTgstjETio4bX+6oLiBnYktn7DjdEslqhffVme4PuBxNojI+uCeg/sn4QV
Ld/iogMJfDWNuLD8326Mi/FE9cCRvFlvAiMSaebMI3zPaySsxTK7Zgj5TpEbmbHI
9wIDAQAB
-----END PUBLIC KEY-----
14 changes: 14 additions & 0 deletions test/static/testshib encryption pub.pem
@@ -0,0 +1,14 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5hqjaroJpB+aR8FME7hQ
9nMV0h7MpKtmgFLcK3vwP67feAK+xdt17i8RyUhxil9FCFR5K08Wjwo3NiHZqHqE
Kitw+IJSndjLSsoNgKEIaiFSug2eV1oYElz06DBXTxc8iq/LazndqTUom51Ode9y
I9AGa88cDM5iOqq9mhuGuvwuLtoyU78Ld+s1Ea6Mgf7L8M7fZVO7Ncu+FgIzI6Gt
035ohYCLBmOoM7o0uj7DcMEvKOMFziwF40wYmyp3hCLlq3qwkM9pTVJltuz0Bt1v
qDdrq3kTheA9JHMayRz3I/BZxAV3iRd4hzLKTkegD8ToTGU10Gme+ZAr1w/erc5h
VrM0/XBmHQlnI5d31GU/mfIkm0XPTGRSpPy7E+dUvj9djvm/VqDdojf3uuwirGeL
MRlO9P/lCerTktW3g27SV8gn3ETm2Mm7rkNqf24KJpDv0tKDosgbdaHr2IEYD4Rp
qySp8kd25BhzushqKRkS8Xu5t7HAlVSHwiFhuLqrr4dUfkB8kZeM/ycfZLCn7oNU
DFdgjGYSVMpakL97sC9slAW4/8UtXXZxLqcyq/YxdpCysPYP1hsAp+VgPC7GI6Cy
iNojKPOptMqLZRYnViKxlOiWBJBzUBRUVuac8LXrMiDw8btWGa1Gh5vThuFUKsvm
Roeuk7eyXEN9J7j6+fTYjnsCAwEAAQ==
-----END PUBLIC KEY-----