
Security News
Security Community Slams MIT-linked Report Claiming AI Powers 80% of Ransomware
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.
@cef-ebsi/siop-auth
Advanced tools
EBSI Auth library for natural persons and legal entities.
npm install @cef-ebsi/siop-auth
or if you use yarn
yarn add @cef-ebsi/siop-auth
The current EBSI SIOP Auth implementation follows RFC - DID-OIDC for NP/LE Authentication to EBSI & Relying Party in EBSI V2, which uses two JSON Web Tokens (JWT), where the Agent uses a DID and it is validated in the DID Registry, and the Relying Party uses an App which is validated in the Trusted Apps Registry.
The current version supports ES256K, ES256, RS256, and EdDSA algorithms.
Note: This version does have support for custom claims. (i.e. using VerifiableID).
The creation of a Relying Party is as follows:
import { RP, Agent, verifyJwtTar, verifyJwtDid } from "@cef-ebsi/siop-auth";
import { generateKeyPair } from "jose";
const privateKeyRP = (await generateKeyPair("ES256K")).privateKey;
const rp = new RP({
  privateKey: privateKeyRP,
  alg: "ES256K",
  name: "test-appj2",
  kid: "https://api-test.ebsi.eu/trusted-apps-registry/v4/apps/test-appj2",
  redirectUri: "http://localhost:3000",
  didRegistry: "https://api-test.ebsi.eu/did-registry/v5/identifiers",
});
The creation of an Agent for Natural Person or Legal Entity is as follows:
const privateKeyAgent = (await generateKeyPair("ES256K")).privateKey;
const agent = new Agent({
  privateKey: privateKeyAgent,
  alg: "ES256K",
  kid: "did:ebsi:z21oU6xvBhsUQM49nw8KydE6#keys-1",
  siopV2: true,
});
The Authentication flow has the following steps involving a Natural Person or Legal Entity (NP/LE) and a relying party (RP):
const uri = await rp.createRequest({
  claims: { ... },
  extraField: "extra data",
});
console.log(uri);
// openid://?response_type=id_token&client_id=http%253A%252F%252Flocalho
// st%253A3000&scope=openid%2520did_authn&nonce=33e7518b-b329-4824-809d-
// d1f548be850d&request=eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLCJraWQiOiJo
// dHRwczovL2FwaS50ZXN0LmludGVic2kueHl6L3RydXN0ZWQtYXBwcy1yZWdpc3RyeS92M
// i9hcHBzLzB4MDQ0ODNiOWJlMWUxODdhYWE2YmUwMzRkNjM0ZmRmMDgyNWRmYWYzNWI4Y2
// UyMjI5YTRjZDNmM2U4ZTg1ZjM0NSJ9.eyJzY29wZSI6Im9wZW5pZCBkaWRfYXV0aG4iLC
// JyZXNwb25zZV90eXBlIjoiaWRfdG9rZW4iLCJyZXNwb25zZV9tb2RlIjoicG9zdCIsImN
// saWVudF9pZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsInJlZGlyZWN0X3VyaSI6Imh0
// dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsIm5vbmNlIjoiMzNlNzUxOGItYjMyOS00ODI0LTgwO
// WQtZDFmNTQ4YmU4NTBkIiwiY2xhaW1zIjp7fSwiZXh0cmFGaWVsZCI6ImV4dHJhIGRhdG
// EiLCJpYXQiOjE2NDQ4MzY3MDEsImlzcyI6InRlc3QtYXBwajIiLCJleHAiOjE2NDQ4Mzc
// wMDF9.AZCS5WartvILNs5pBhIXPlmVi8ZI65obdBM36ZPLY5FxnQF6d7sRodsXqKbIAvX
// wTxCdh024bXeK6yNVzH4dfg
const urlParams = new URLSearchParams(uri.replace("openid://?", ""));
const { payload: payloadReq } = await verifyJwtTar(urlParams.get("request"), {
  trustedAppsRegistry: "https://api-test.ebsi.eu/trusted-apps-registry/v4/apps",
});
console.log(payloadReq);
// {
//   scope: 'openid did_authn',
//   response_type: 'id_token',
//   response_mode: 'post',
//   client_id: 'http://localhost:3000',
//   redirect_uri: 'http://localhost:3000',
//   nonce: '33e7518b-b329-4824-809d-d1f548be850d',
//   claims: {},
//   extraField: 'extra data',
//   iat: 1644836701,
//   iss: 'test-appj2',
//   exp: 1644837001
// }
const encryptionKeyPair =
  alg === "EdDSA"
    ? crypto.generateKeyPairSync("x25519")
    : await generateKeyPair(alg);
const publicEncryptionKeyJwk = await exportJWK(encryptionKeyPair.publicKey);
const privateEncryptionKeyJwk = await exportJWK(encryptionKeyPair.privateKey);
const nonce = uuidv4();
const { urlEncoded } = await agent.createResponse({
  nonce,
  redirectUri: "http://localhost:3000",
  claims: {
    encryption_key: publicEncryptionKeyJwk,
  },
  extraField: "extra data",
});
console.log(urlEncoded);
// http://localhost:3000#id_token=eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLC
// JraWQiOiJkaWQ6ZWJzaTp6MjFvVTZ4dkJoc1VRTTQ5bnc4S3lkRTYja2V5cy0xIn0.eyJ
// zdWIiOiI2dTVlUW0zVVZnMTBoa0VOcGMzVVhxQ3lIbVp2WDhaVG16MHo0LW1lcnJvIiwi
// YXVkIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwic3ViX2p3ayI6eyJrdHkiOiJFQyIsI
// mNydiI6InNlY3AyNTZrMSIsIngiOiJJR292OXFSV2Q5M1E4S0ZaSWtsaUNSaGtwZmZTVW
// 1hejZjS2JJM0txc0lNIiwieSI6ImE3WFVGSFBCYjRSOVBXUkg1TXY5UWdVLXlHOW51YTF
// lbFJPTFVxMk5lZ2cifSwibm9uY2UiOiI5NWYyZjUxNi1jYjIwLTQwMzMtOTU1Yy1mNjc5
// MWU5Mzk0NjAiLCJjbGFpbXMiOnsiZW5jcnlwdGlvbl9rZXkiOnsia3R5IjoiRUMiLCJjc
// nYiOiJzZWNwMjU2azEiLCJ4IjoiSU1QbFdTSS14TkloQkFBNjRaZ3ZYZFlxWXl4U3dfYW
// wtMHZlWkFsbFVEQSIsInkiOiJHRThEcEdhRExobEs4MlJxQVVHZHVBOHhGS3RMUDQ2SUd
// TdWJnNndSVC1nIn19LCJleHRyYUZpZWxkIjoiZXh0cmEgZGF0YSIsImlhdCI6MTY0NDgz
// NjcwMiwiaXNzIjoiaHR0cHM6Ly9zZWxmLWlzc3VlZC5tZS92MiIsImV4cCI6MTY0NDgzN
// zAwMn0.9XIcv31iw0FqJ6AEmYMmAcf7s3kBTeA_S1vWf8231Qrg6bXILeezBzdHiIOexN
// EnuwtRvvtuS0EycS7B1Ke_mw
const idTokenAuthResponse = new URLSearchParams(
  urlEncoded.substring(urlEncoded.indexOf("#") + 1)
).get("id_token") as string;
const resVerification = await RP.verifyResponse(
  idTokenAuthResponse,
  async (claims) => {
    if (!claims || !claims.encryption_key)
      throw new Error("no encryption_key found in the claims");
  const { didDocument } = await verifyJwtDid(idTokenAuthResponse, {
    didRegistry: "https://api-test.ebsi.eu/did-registry/v5/identifiers",
  });
  const did = didDocument?.id ?? "";
    return { ...claims, did };
  }
);
console.log(resVerification);
// {
//   payload: {
//     did: 'did:ebsi:z21oU6xvBhsUQM49nw8KydE6',
//     sub: '6u5eQm3UVg10hkENpc3UXqCyHmZvX8ZTmz0z4-merro',
//     aud: 'http://localhost:3000',
//     sub_jwk: {
//       kty: 'EC',
//       crv: 'secp256k1',
//       x: 'IGov9qRWd93Q8KFZIkliCRhkpffSUmaz6cKbI3KqsIM',
//       y: 'a7XUFHPBb4R9PWRH5Mv9QgU-yG9nua1elROLUq2Negg'
//     },
//     nonce: '95f2f516-cb20-4033-955c-f6791e939460',
//     claims: { encryption_key: { ... } },
//     extraField: 'extra data',
//     iat: 1644836702,
//     iss: 'https://self-issued.me/v2',
//     exp: 1644837002
//   },
//   header: {
//     alg: 'ES256K',
//     typ: 'JWT',
//     kid: 'did:ebsi:z21oU6xvBhsUQM49nw8KydE6#keys-1'
//   },
//   resultClaims: {
//     encryption_key: {
//       kty: 'EC',
//       crv: 'secp256k1',
//       x: 'IMPlWSI-xNIhBAA64ZgvXdYqYyxSw_al-0veZAllUDA',
//       y: 'GE8DpGaDLhlK82RqAUGduA8xFKtLP46IGSubg6wRT-g'
//     },
//     did: 'did:ebsi:z21oU6xvBhsUQM49nw8KydE6'
//   }
// }
const akeAccessToken = await rp.createAccessToken(resVerification);
console.log(akeAccessToken);
// {
//   ake1_enc_payload: '72da437d06839e054726e13df14fec940286ad1985026d50
//     e8fdd652402378c1986d1505f336765f1ae1be114b347225b298c4a4ab9c8031c
//     614e01ec96c4edcc9f0353b8bfee8a16220adf3f4a71e50f2b1a326c8ca1f6750
//     dcf4929ff19b0f1685e83533dd12d5c9db88636ba39175e2532e47a526edc612f
//     d7b56008a6a49f6bd52c96dcf38065a644e613772bb15037381a755d7663dace9
//     bb39abc2a3e8e4e0d59f86260d6043bc6171d97df581ca612239cd8007521b2d9
//     ccf3dc807189b25dfa4b645f5daa911c434e273ab2d82dd07efe44e16580248e5
//     360801ffbdc9e6e84795ea97c4c3cff3d187dc50c3e1d3f9b3d4b1ab5e0f01123
//     de96c1ef3a6fccd824ebdd5dd5d1a0238e25df3c1d3287cbd240071489d307edd
//     c4452e3e88a141b70e470e517af30fbb8aa0a75f74898e7af25cf51f7676de9b5
//     2cf2ee67033c27e6e94d9592d2a87a7c3b937b7f17b568060d4dbc42995a3da5d
//     2179876d12baf664e1b1d2bddb2c80f491a4a33949a3b3e2f1bb50a1a1b90b656
//     1470eace49149564b34ea9adad45c6f51dc6985a928546cea9b20679ebb797bc2
//     13b5e5773bc870c143cbbe82b34f5ba3479b45c53c0c96ed66da08b173b5fce82
//     9feed4d45d3187d37a87ef77a5f9d55bb226b8c8c31065bf8d7f66d4051ddc26c
//     6dd288859db9cd49258f9da9d72ca10f69050d554a30c4112d562db6773424237
//     24abfd608105931a75fedf483b2dd67d0316138f68e6b7f6b9ba0ea8ffc1e0ea3
//     b482810de56192b0d6af7adcc6905cc767a5f58d3c25e5c48b353bc14d2d0f964
//     a2b475bcfddcd6774d9d1c9cda7ab37b0f5056f031001e76c524606c0a9ed1f1c
//     01ec3d00c4fb3b7e6af6f72cb0eb7e85c3cb8ee1cd65b9fbcff6a975ecd6b4c6a
//     113cc8ec2ff58bfb3c0fbb7e68cdbea82398a040ddb2a89cb0da32561e5cb4837
//     618c33eaa753dd8e438eac938206e3a6e9020c98525aa5715580bbbc7169ecfd9
//     30269eae30be3c06c3fdfc24a7c64c9358c1239a073a880535dd788eba3c4b458
//     9b2db371d9ffd93ae7401ebe52ad71f8454ce36c7bbb2b346208db2c72ee3577e
//     70b0e1f8b70e40a0ca216220bb74d697f207bcca562d956380247e9fbfbdc68ad
//     90f5648d2cdeff24aa9889d3625979adef35a1941c34b01d5282cc3880dbc3105
//     f50bb4a80f4cccf7d155b02a618dfc87cf9f23dd15f4d03b509a16e356514922b
//     865858368a359aca260fe84969e3c6282c7c7442f0e3a690804e68d1ba9f9f73b
//     b61dd15864b72a7e27b4018',
//   ake1_sig_payload: {
//     ake1_nonce: '95f2f516-cb20-4033-955c-f6791e939460',
//     ake1_enc_payload: '72da437d06839e054726e13df14fec940286ad1985026d
//       50e8fdd652402378c1986d1505f336765f1ae1be114b347225b298c4a4ab9c8
//       031c614e01ec96c4edcc9f0353b8bfee8a16220adf3f4a71e50f2b1a326c8ca
//       1f6750dcf4929ff19b0f1685e83533dd12d5c9db88636ba39175e2532e47a52
//       6edc612fd7b56008a6a49f6bd52c96dcf38065a644e613772bb15037381a755
//       d7663dace9bb39abc2a3e8e4e0d59f86260d6043bc6171d97df581ca612239c
//       d8007521b2d9ccf3dc807189b25dfa4b645f5daa911c434e273ab2d82dd07ef
//       e44e16580248e5360801ffbdc9e6e84795ea97c4c3cff3d187dc50c3e1d3f9b
//       3d4b1ab5e0f01123de96c1ef3a6fccd824ebdd5dd5d1a0238e25df3c1d3287c
//       bd240071489d307eddc4452e3e88a141b70e470e517af30fbb8aa0a75f74898
//       e7af25cf51f7676de9b52cf2ee67033c27e6e94d9592d2a87a7c3b937b7f17b
//       568060d4dbc42995a3da5d2179876d12baf664e1b1d2bddb2c80f491a4a3394
//       9a3b3e2f1bb50a1a1b90b6561470eace49149564b34ea9adad45c6f51dc6985
//       a928546cea9b20679ebb797bc213b5e5773bc870c143cbbe82b34f5ba3479b4
//       5c53c0c96ed66da08b173b5fce829feed4d45d3187d37a87ef77a5f9d55bb22
//       6b8c8c31065bf8d7f66d4051ddc26c6dd288859db9cd49258f9da9d72ca10f6
//       9050d554a30c4112d562db677342423724abfd608105931a75fedf483b2dd67
//       d0316138f68e6b7f6b9ba0ea8ffc1e0ea3b482810de56192b0d6af7adcc6905
//       cc767a5f58d3c25e5c48b353bc14d2d0f964a2b475bcfddcd6774d9d1c9cda7
//       ab37b0f5056f031001e76c524606c0a9ed1f1c01ec3d00c4fb3b7e6af6f72cb
//       0eb7e85c3cb8ee1cd65b9fbcff6a975ecd6b4c6a113cc8ec2ff58bfb3c0fbb7
//       e68cdbea82398a040ddb2a89cb0da32561e5cb4837618c33eaa753dd8e438ea
//       c938206e3a6e9020c98525aa5715580bbbc7169ecfd930269eae30be3c06c3f
//       dfc24a7c64c9358c1239a073a880535dd788eba3c4b4589b2db371d9ffd93ae
//       7401ebe52ad71f8454ce36c7bbb2b346208db2c72ee3577e70b0e1f8b70e40a
//       0ca216220bb74d697f207bcca562d956380247e9fbfbdc68ad90f5648d2cdef
//       f24aa9889d3625979adef35a1941c34b01d5282cc3880dbc3105f50bb4a80f4
//       cccf7d155b02a618dfc87cf9f23dd15f4d03b509a16e356514922b865858368
//       a359aca260fe84969e3c6282c7c7442f0e3a690804e68d1ba9f9f73bb61dd15
//       864b72a7e27b4018',
//     did: 'did:ebsi:z21oU6xvBhsUQM49nw8KydE6',
//     iat: 1644836702,
//     iss: 'test-appj2',
//     exp: 1644837602
//   },
//   ake1_jws_detached: 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLCJraWQiOiJ
//     odHRwczovL2FwaS50ZXN0LmludGVic2kueHl6L3RydXN0ZWQtYXBwcy1yZWdpc3Ry
//     eS92Mi9hcHBzLzB4MDQ0ODNiOWJlMWUxODdhYWE2YmUwMzRkNjM0ZmRmMDgyNWRmY
//     WYzNWI4Y2UyMjI5YTRjZDNmM2U4ZTg1ZjM0NSJ9..FDIeLfGMw6rehGvvIMu7ybpf
//     g7BNDBDBHMMIfLm-9kfe9HNwFYh8jgjI7Z5bdl-u7-e9HPzfGMXuEgOHv15t3g',
//   kid: 'https://api-test.ebsi.eu/trusted-apps-registry/v4/apps/test-appj2'
// }
const accessToken = await Agent.verifyAkeResponse(akeAccessToken, {
  nonce,
  privateEncryptionKeyJwk,
  trustedAppsRegistry: "https://api-test.ebsi.eu/trusted-apps-registry/v4/apps",
  alg: "ES256K",
});
console.log(accessToken);
// eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLCJraWQiOiJodHRwczovL2FwaS50ZXN0L
// mludGVic2kueHl6L3RydXN0ZWQtYXBwcy1yZWdpc3RyeS92Mi9hcHBzLzB4MDQ0ODNiOW
// JlMWUxODdhYWE2YmUwMzRkNjM0ZmRmMDgyNWRmYWYzNWI4Y2UyMjI5YTRjZDNmM2U4ZTg
// 1ZjM0NSJ9.eyJzdWIiOiJkaWQ6ZWJzaTp6MjFvVTZ4dkJoc1VRTTQ5bnc4S3lkRTYiLCJ
// kaWQiOiJkaWQ6ZWJzaTp6MjFvVTZ4dkJoc1VRTTQ5bnc4S3lkRTYiLCJhdWQiOiJlYnNp
// LWNvcmUtc2VydmljZXMiLCJub25jZSI6IjQ3M2M3N2VkLTZiOWItNDVjNi1hNThhLTgyM
// WI3NjA0NThmZiIsImxvZ2luX2hpbnQiOiJkaWRfc2lvcCIsImlhdCI6MTY0NDgzNjcwMi
// wiaXNzIjoidGVzdC1hcHBqMiIsImV4cCI6MTY0NDgzNzYwMn0.tlDsRB3w78DRdPhsL95
// mkOjB3x4Kmj7MHJisphOtUiM-v2_EoFLSACGBVPRd_YK9DWvNQ2bxR1BQbgRBgjdQtg
await verifyJwtTar(accessToken, {
  trustedAppsRegistry: "https://api-test.ebsi.eu/trusted-apps-registry/v4/apps",
  audience: "ebsi-core-services",
});
It is assumed that the RP has an app registered in the trusted apps registry.
The DID Method version 2 is also supported. Here is an example to create an agent for natural persons:
import { Agent } from "@cef-ebsi/siop-auth";
import { calculateJwkThumbprint, exportJWK, generateKeyPair, JWK } from "jose";
const keyPair = await generateKeyPair(alg);
const publicKeyJwkAgent = await exportJWK(keyPair.publicKey);
const thumbprint = await calculateJwkThumbprint(publicKeyJwkAgent, "sha256");
const subjectIdentifier = Buffer.from(thumbprint, "base64");
const kidAgent = `${EbsiWallet.createDid(
  "NATURAL_PERSON",
  subjectIdentifier,
)}#${thumbprint}`;
const agent = new Agent({
  privateKey: keyPair.privateKey,
  alg,
  kid: kidAgent,
  siopV2: true,
});
When creating the authentication response set the syntaxType to "did_subject" in the options in order to create the ID Token with the JWK in the headers. Example:
const { idToken } = await agent.createResponse(
  {
    nonce,
    redirectUri: callbackUrl,
    claims: {
      encryption_key: publicKeyEncryptionJwk,
    },
    responseMode: "form_post",
  },
  {
    syntaxType: "did_subject",
  },
);
To run e2e you need to set these two environment variables either in a .env or passing as a parameter to yarn test:e2e.
You can use the .env.example from the repo and renamed it to .env.
# unit tests
$ yarn test:unit
# e2e tests
$ yarn test:e2e
# all tests
$ yarn test
Copyright (c) 2019 European Commission
Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence");
You may not use this work except in compliance with the Licence.
You may obtain a copy of the Licence at:
Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licence for the specific language governing permissions and limitations under the Licence.
FAQs
EBSI DID Auth library
The npm package @cef-ebsi/siop-auth receives a total of 11 weekly downloads. As such, @cef-ebsi/siop-auth popularity was classified as not popular.
We found that @cef-ebsi/siop-auth demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.

Research
/Security News
Socket researchers found 10 typosquatted npm packages that auto-run on install, show fake CAPTCHAs, fingerprint by IP, and deploy a credential stealer.