This page looks at some of the new features introduced from the release of CryptoSys PKI Pro 1.0 in March 2015 to the release of CryptoSys PKI Pro 2.0 in October 2020.
Some sample C# and VBA/VB6 code below.
Console.WriteLine("\nECDH SHARED SECRET USING P-256:"); // Ref: CAVS 14.1 ECC CDH Primitive (SP800 - 56A Section 5.7.1.2) // Test Information for "testecccdh" ecccdhtestvectors.zip // [P-256] Ecc.CurveName curve = Ecc.CurveName.P_256; // Our private key is dUIT: string ourPrivateKeyHex = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"; // Their public key as hex is "04" || QCAVSx || QCAVSy string theirPublicKeyHex = "04" + "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" + "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"; // Correct expected result string zzOK = "46FC62106420FF012E54A434FBDD2D25CCC5852060561E68040DD7778997BD7B"; string ourPrivateKey = Ecc.ReadKeyByCurve(ourPrivateKeyHex, curve); Console.WriteLine("Curve = {0}", Ecc.QueryKey(ourPrivateKey, "curveName")); Console.WriteLine("Our private key has {0} bits", Ecc.QueryKey(ourPrivateKey, "keyBits")); string theirPublicKey = Ecc.ReadKeyByCurve(theirPublicKeyHex, curve); Console.WriteLine("Their public key has {0} bits", Ecc.QueryKey(theirPublicKey, "keyBits")); // Compute shared secret byte[] zz = Ecc.DHSharedSecret(ourPrivateKey, theirPublicKey); Console.WriteLine("ZZ={0}", Cnv.ToHex(zz)); Debug.Assert(Cnv.ToHex(zz) == zzOK, "Ecc.DHSharedSecret failed");
For similar code using VBA/VB6 see the example in ECC_DHSharedSecret and the (shorter) example below. This shorter example uses the new VBA/VB6 wrapper functions introduced v20.0.1.
Debug.Print "Testing ECC_DHSharedSecret ..." Dim strOurPriKeyHex As String Dim strTheirPubKeyHex As String Dim strOurPrivateKey As String Dim strTheirPublicKey As String Dim strCurveName As String Dim strCorrectHex As String Dim lpZZ() As Byte ' Ref: CAVS 14.1 ECC CDH Primitive (SP800 - 56A Section 5.7.1.2) ' Test Information for "testecccdh" ecccdhtestvectors.zip '[P-256] strCurveName = "P-256" ' Our private key is dUIT: strOurPriKeyHex = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534" ' Their public key as hex is "04" || QCAVSx || QCAVSy strTheirPubKeyHex = "04" & "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" _ + "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac" ' Correct result is ZIUT strCorrectHex = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" Debug.Print "Test for curve " & strCurveName & " ..." ' Read in keys to internal key strings ' Our private key... strOurPrivateKey = eccReadKeyByCurve(strOurPriKeyHex, strCurveName, 0) Debug.Assert Len(strOurPrivateKey) > 0 ' Check the key we read in Debug.Print "Our private key has " & ECC_QueryKey("", 0, strOurPrivateKey, "keyBits", 0) & " bits" ' Their public key... strTheirPublicKey = eccReadKeyByCurve(strTheirPubKeyHex, strCurveName, 0) Debug.Assert Len(strTheirPublicKey) > 0 ' Check the key we read in Debug.Print "Their public key has " & ECC_QueryKey("", 0, strTheirPublicKey, "keyBits", 0) & " bits" ' Compute shared secret lpZZ = eccDHSharedSecret(strOurPrivateKey, strTheirPublicKey, 0) Debug.Assert cnvBytesLen(lpZZ) > 0 Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ) ' Check the result Debug.Print "OK=" & strCorrectHex Debug.Assert UCase(cnvHexStrFromBytes(lpZZ)) = UCase(strCorrectHex)
Console.WriteLine("\nECDH SHARED SECRET USING X25519:"); // Ref: RFC7748 Section 6.1 // https://tools.ietf.org/html/rfc7748#section-6.1 /* Test vector: Alice's private key, a: 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a Alice's public key, X25519(a, 9): 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a Bob's private key, b: 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb Bob's public key, X25519(b, 9): de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f Their shared secret, K: 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 */ Ecc.CurveName curve = Ecc.CurveName.X25519; string alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"; string alicePublicKeyHex = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"; string bobPrivateKeyHex = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"; string bobPublicKeyHex = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"; // Correct expected result string zzOK = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"; // 1. Alice's private + Bob's public // NB we *must* specify whether X25519 keys are public or private string ourPrivateKey = Ecc.ReadKeyByCurve(alicePrivateKeyHex, curve, Ecc.KeyType.PrivateKey); Console.WriteLine("Curve = {0}", Ecc.QueryKey(ourPrivateKey, "curveName")); Console.WriteLine("Our private key has {0} bits", Ecc.QueryKey(ourPrivateKey, "keyBits")); string theirPublicKey = Ecc.ReadKeyByCurve(bobPublicKeyHex, curve, Ecc.KeyType.PublicKey); Console.WriteLine("Their public key has {0} bits", Ecc.QueryKey(theirPublicKey, "keyBits")); // Compute shared secret byte[] zz1 = Ecc.DHSharedSecret(ourPrivateKey, theirPublicKey); Console.WriteLine("ZZ={0}", Cnv.ToHex(zz1)); Debug.Assert(Cnv.ToHex(zz1).ToLower() == zzOK, "Ecc.DHSharedSecret failed"); // 2. Bob's private + Alice's public ourPrivateKey = Ecc.ReadKeyByCurve(bobPrivateKeyHex, curve, Ecc.KeyType.PrivateKey); theirPublicKey = Ecc.ReadKeyByCurve(alicePublicKeyHex, curve, Ecc.KeyType.PublicKey); // Compute shared secret byte[] zz2 = Ecc.DHSharedSecret(ourPrivateKey, theirPublicKey); Console.WriteLine("ZZ={0}", Cnv.ToHex(zz2)); Debug.Assert(Cnv.ToHex(zz2).ToLower() == zzOK, "Ecc.DHSharedSecret failed");
' Ref: RFC7748 Section 6.1 ' https://tools.ietf.org/html/rfc7748#section-6.1 ' ' Test vector: ' Alice's private key, a: ' 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a ' Alice's public key, X25519(a, 9): ' 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a ' Bob's private key, b: ' 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb ' Bob's public key, X25519(b, 9): ' de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f ' Their shared secret, K: ' 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 ' NB uses functions in basCrPKIWrappers.bas, available in v20.0.1 Dim curveName As String Dim alicePrivateKeyHex As String Dim alicePublicKeyHex As String Dim bobPrivateKeyHex As String Dim bobPublicKeyHex As String Dim zzOK As String Dim ourPrivateKey As String Dim theirPublicKey As String Dim zz1() As Byte Dim zz2() As Byte curveName = "X25519" alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a" alicePublicKeyHex = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" bobPrivateKeyHex = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb" bobPublicKeyHex = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f" ' Correct expected result zzOK = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" ' 1. Alice's private + Bob's public ' NB we *must* specify whether X25519 keys are public or private ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY) Debug.Assert Len(ourPrivateKey) > 0 Debug.Print "Our private key has " & ECC_QueryKey("", 0, ourPrivateKey, "keyBits", 0) & " bits" theirPublicKey = eccReadKeyByCurve(bobPublicKeyHex, curveName, PKI_ECC_PUBLIC_KEY) Debug.Assert Len(theirPublicKey) > 0 Debug.Print "Their public key has " & ECC_QueryKey("", 0, theirPublicKey, "keyBits", 0) & " bits" ' Compute shared secret zz1 = eccDHSharedSecret(ourPrivateKey, theirPublicKey, 0) Debug.Print "ZZ=" & cnvHexStrFromBytes(zz1) Debug.Assert StrComp(cnvHexStrFromBytes(zz1), zzOK, vbTextCompare) = 0
Console.WriteLine("\nCREATE A SELF-SIGNED X.509 CERTIFICATE USING Ed25519:"); // Ref: [RFC8410] https://tools.ietf.org/html/rfc8410 string dn, extns, certname, prikeyfile, query; string pubkeystr, issuercert; X509.KeyUsageOptions keyUsage; int r; string s; // 1. Create a new self-*signed* certificate using the Ed25519 key in RFC8410 certname = "ietf-Ed25519-self.cer"; prikeyfile = "edwards-ietf.p8"; // No password dn = "CN=IETF Test Demo"; extns = "notBefore=2016-01-01;notAfter=2040-12-31"; //Digital Signature, Certificate Signing, [Off-line CRL Signing], CRL Signing keyUsage = X509.KeyUsageOptions.DigitalSignature | X509.KeyUsageOptions.KeyCertSign | X509.KeyUsageOptions.CrlSign; r = X509.MakeCertSelf(certname, prikeyfile, 0x0ED25519, 0, dn, extns, keyUsage, "", SigAlgorithm.Ed25519, X509.CertOptions.UTF8String); Console.WriteLine("X509.MakeCertSelf returns {0} (expecting 0)", r); Debug.Assert(0 == r, "X509.MakeCertSelf failed"); // Dump details Console.WriteLine("FILE: {0}", certname); Console.WriteLine(X509.TextDumpToString(certname, 0)); // Do a query on the cert query = "signatureAlgorithm"; s = X509.QueryCert(certname, query); Console.WriteLine("{0}={1}", query, s); Debug.Assert(s.Length > 0, "X509.QueryCert failed"); // 2. Now create a self-*issued* cert using Ed25519 to sign an X25519 public key // [RFC8410] 10.2. Example X25519 Certificate // NB This is self-*issued* in that the public key is for an X25519 key intended for ECDH, // but it is signed using an Ed25519 signature with a key also belonging to ones self. // Read in X25519 public key from its hex value // NB we *must* specify that it's a public key pubkeystr = Ecc.ReadKeyByCurve("8520F0098930A754748B7DDCB43EF75A0DBF3A0D26381AF4EBA4A98EAA9B4E6A", Ecc.CurveName.X25519, Ecc.KeyType.PublicKey); Debug.Assert(pubkeystr.Length > 0, "Ecc.ReadKeyByCurve failed"); // Set cert parameters to closely duplicate the cert given in RFC8410 (almost!) dn = "CN=IETF Test Demo"; extns = "notBefore=2016-08-01T12:19:24;notAfter=2040-12-31T23:59:59;keyUsage=noncritical;serialNumber=#x5601474A2A8DC330;" + "subjectKeyIdentifier=9B1F5EEDED043385E4F7BC623C5975B90BC8BB3B"; keyUsage = X509.KeyUsageOptions.KeyAgreement; issuercert = certname; // Use the self-signed cert we made above to issue this new cert certname = "ietf-X25519-self-issued.cer"; r = X509.MakeCert(certname, issuercert, pubkeystr, prikeyfile, 0, 0, dn, extns, keyUsage, "", SigAlgorithm.Ed25519, X509.CertOptions.UTF8String); Console.WriteLine("X509.MakeCert returns {0} (expecting 0)", r); Debug.Assert(0 == r, "X509.MakeCert failed"); // Dump details Console.WriteLine("FILE: {0}", certname); Console.WriteLine(X509.TextDumpToString(certname, 0)); // Verify that this cert was signed by the above r = X509.VerifyCert(certname, issuercert); Console.WriteLine("X509.VerifyCert returns {0} (expecting 0 => verified OK)", r); Debug.Assert(0 == r, "X509.VerifyCert failed");
CREATE A SELF-SIGNED X.509 CERTIFICATE USING Ed25519: X509.MakeCertSelf returns 0 (expecting 0) FILE: ietf-Ed25519-self.cer X.509 CERTIFICATE Version: 3 Serial Number: #x0ED25519 Issuer: CN=IETF Test Demo Subject: CN=IETF Test Demo Validity: NotBefore: 2016-01-01T00:00:01Z NotAfter: 2040-12-31T23:59:59Z Subject Public Key Algorithm: Ed25519 ECC key length: 256 bits Curve: Ed25519 Public Key Value: 19 BF 44 09 69 84 CD FE 85 41 BA C1 67 DC 3B 96 C8 50 86 AA 30 B6 B6 CB 0C 5C 38 AD 70 31 66 E1 X509v3 Extensions: Subject Type: CA Key Usage[!]: digitalSignature,keyCertSign,cRLSign Signature Algorithm: Ed25519 Signature Hash Algorithm: sha512 Signature Value: 08 AD 57 0F C2 38 FF 32 F0 7D F3 3B 2E 50 7E 1E 9A 0D 69 56 1D C8 F8 64 BF C5 5E B3 6D E3 4E 68 7C C9 C9 A0 B2 18 42 A7 B9 CA 4A 81 FA CD E7 2A 68 C0 D2 F9 F6 BD 4B A6 C3 01 25 CC 59 A4 E1 06 SHA-1 Thumbprint: 0ec7fcf0df37594d947bd09cbbb8c014d5aec0e0 SHA-256 Thumbprint: 42c8ca8d6f22e46e29f3efdffc74e1c16d297179dfcd16eb7b5bdc6100240690 signatureAlgorithm=Ed25519 X509.MakeCert returns 0 (expecting 0) FILE: ietf-X25519-self-issued.cer X.509 CERTIFICATE Version: 3 Serial Number: #x5601474A2A8DC330 Issuer: CN=IETF Test Demo Subject: CN=IETF Test Demo Validity: NotBefore: 2016-08-01T12:19:24Z NotAfter: 2040-12-31T23:59:59Z Subject Public Key Algorithm: X25519 ECC key length: 256 bits Curve: X25519 Public Key Value: 85 20 F0 09 89 30 A7 54 74 8B 7D DC B4 3E F7 5A 0D BF 3A 0D 26 38 1A F4 EB A4 A9 8E AA 9B 4E 6A X509v3 Extensions: Subject Type: End Entity Key Usage: keyAgreement Subject Key Identifier: 9b1f5eeded043385e4f7bc623c5975b90bc8bb3b Signature Algorithm: Ed25519 Signature Hash Algorithm: sha512 Signature Value: 44 1D 2A A4 48 FB 8E 71 89 99 9C 63 FD 5E 23 0D FA 67 A3 F8 1A 1E 62 18 00 4A CA 1C E8 96 EB FD CC F3 7F 8F 47 25 61 5B 92 D4 F3 F0 AC A3 C8 4F 50 2C 34 5E 90 E7 61 95 CF 9E 4B F4 B6 BA 03 04 SHA-1 Thumbprint: 1e9685c30312d596f7d079fc4c5086166b3ed6fb SHA-256 Thumbprint: 966e6c7ca1c70de8a32f1a327595053bbd4c18627eef1e20ecc44835656ba528 X509.VerifyCert returns 0 (expecting 0 => verified OK)
To contact us or comment on this page, please send us a message.
This page last updated 25 October 2023