SSE4E GPError GPSystem ByteString ByteBuffer TLV TLVList Card Atr Key Crypto Application GPApplication GPSecDomain ASN1 CardFile IsoSecureChannel ApplFactory GPXML JsScript CardSim X509 CRL KeyStore CMSSignedData CMSGenerator XMLSignature OCSPQuery LDAP SOAP URLConnection PKCS11Provider PKCS11Session PKCS11Object OutlineNode OpenSCDP |
Crypto - Reference DocumentationImplements access to cryptographic services. Index of Methods
Constants
ConstructorPrototypeCrypto() Crypto(String provider) DescriptionCreate a crypto object and bind it to the given cryptographic service provider. If no provider is defined, then the default provider "BC" will be used.Arguments
Exceptions
Examplecrypto = new Crypto(); assert(crypto != null); crypto = new Crypto("BC"); assert(crypto != null); encrypt()PrototypeByteString encrypt(Key key, Number mech, ByteString data) ByteString encrypt(Key key, Number mech, ByteString data, ByteString iv) DescriptionEncrypt the plain data using the algorithm defined by mech and the specified key. The Crypto.RSA mechanism performs a plain RSA encrypt operation with no encoding format. The Crypto.RSA_ISO9796_2 mechanism performs a plain RSA encrypt operation with no encoding format but according to ISO 9697-2. The result is less than half of the modulus. The Crypto.PKCS1 mechanism performs a plain RSA encrypt operation with PKCS1 V1.5 encoding format. The Crypto.OAEP_XXX mechanism performs a plain RSA encrypt operation with PKCS1 V2.1 OEAP encoding format using the selected message digest algorithm. If the algorithm requires an initialisation vector, then the additional argument iv must be specified (DES_CBC, AES_CBC or AES_CTR). Arguments
Return
Exceptions
Example// Instantiate crypto service var crypto = new Crypto(); // Define 3 different single DES key values var key1 = new ByteString("7CA110454A1A6E57", HEX); var key2 = new ByteString("0131D9619DC1376E", HEX); var key3 = new ByteString("9DC1376E0131D961", HEX); var plain = new ByteString("01A1D6D039776742", HEX); var cipher; var result; // Create three single DES keys, a double DES key and a triple DES key var deskey1 = new Key(); deskey1.setComponent(Key.DES, key1); var deskey2 = new Key(); deskey2.setComponent(Key.DES, key2); var deskey3 = new Key(); deskey3.setComponent(Key.DES, key3); var des2key = new Key(); des2key.setComponent(Key.DES, key1.concat(key2)); var des3key = new Key(); des3key.setComponent(Key.DES, key1.concat(key2).concat(key3)); // Single DES ECB encrypt cipher = new ByteString("690F5B0D9A26939B", HEX); result = crypto.encrypt(deskey1, Crypto.DES_ECB, plain); assert(result.equals(cipher)); // Single DES ECB decrypt result = crypto.decrypt(deskey1, Crypto.DES_ECB, cipher); assert(result.equals(plain)); // Double DES ECB encrypt cipher = plain; cipher = crypto.encrypt(deskey1, Crypto.DES_ECB, cipher); cipher = crypto.decrypt(deskey2, Crypto.DES_ECB, cipher); cipher = crypto.encrypt(deskey1, Crypto.DES_ECB, cipher); result = crypto.encrypt(des2key, Crypto.DES_ECB, plain); assert(result.equals(cipher)); // Double DES ECB decrypt result = crypto.decrypt(des2key, Crypto.DES_ECB, cipher); assert(result.equals(plain)); // Triple DES ECB encrypt cipher = plain; cipher = crypto.encrypt(deskey1, Crypto.DES_ECB, cipher); cipher = crypto.decrypt(deskey2, Crypto.DES_ECB, cipher); cipher = crypto.encrypt(deskey3, Crypto.DES_ECB, cipher); result = crypto.encrypt(des3key, Crypto.DES_ECB, plain); assert(result.equals(cipher)); // Triple DES ECB decrypt result = crypto.decrypt(des3key, Crypto.DES_ECB, cipher); assert(result.equals(plain)); // Single DES CBC encrypt var plain = new ByteString("01A1D6D0397767423977674201A1D6D0", HEX); var iv = new ByteString("59D9839733B8455D", HEX); var v; v = plain.bytes(0, 8); v = v.xor(iv); v = crypto.encrypt(deskey1, Crypto.DES_ECB, v); cipher = v; v = plain.bytes(8, 8); v = cipher.xor(v); v = crypto.encrypt(deskey1, Crypto.DES_ECB, v); cipher = cipher.concat(v); result = crypto.encrypt(deskey1, Crypto.DES_CBC, plain, iv); assert(result.equals(cipher)); // Single DES CBC decrypt result = crypto.decrypt(deskey1, Crypto.DES_CBC, cipher, iv); assert(result.equals(plain)); // Encrypt and decrypt with AES key var key = new Key(); // Make key a 128 bit AES key key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f", HEX)); var plain = new ByteString("00112233445566778899aabbccddeeff", HEX); var cipher = new ByteString("69c4e0d86a7b0430d8cdb78070b4c55a", HEX); var result = crypto.encrypt(key, Crypto.AES_ECB, plain); assert(cipher.equals(result)); var result = crypto.decrypt(key, Crypto.AES_ECB, cipher); assert(plain.equals(result)); // Make key a 192 bit AES key key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f1011121314151617", HEX)); var plain = new ByteString("00112233445566778899aabbccddeeff", HEX); var cipher = new ByteString("dda97ca4864cdfe06eaf70a0ec0d7191", HEX); var result = crypto.encrypt(key, Crypto.AES_ECB, plain); assert(cipher.equals(result)); var result = crypto.decrypt(key, Crypto.AES_ECB, cipher); assert(plain.equals(result)); // Make key a 256 bit AES key key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", HEX)); var plain = new ByteString("00112233445566778899aabbccddeeff", HEX); var cipher = new ByteString("8ea2b7ca516745bfeafc49904b496089", HEX); var result = crypto.encrypt(key, Crypto.AES_ECB, plain); assert(cipher.equals(result)); var result = crypto.decrypt(key, Crypto.AES_ECB, cipher); assert(plain.equals(result)); // AES CTR mode key.setComponent(Key.AES, new ByteString("2b7e151628aed2a6abf7158809cf4f3c", HEX)); var plain = new ByteString("6bc1bee22e409f96e93d7e117393172a", HEX); var cipher = new ByteString("874d6191b620e3261bef6864990db6ce", HEX); var iv = new ByteString("F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF", HEX); var result = crypto.encrypt(key, Crypto.AES_CTR, plain, iv); assert(cipher.equals(result)); var result = crypto.decrypt(key, Crypto.AES_CTR, cipher, iv); assert(plain.equals(result)); // Decrypt and encrypt as basically the same in CTR mode var result = crypto.encrypt(key, Crypto.AES_CTR, cipher, iv); assert(plain.equals(result)); // RSA encrypt with plain input block // Make RSA private key from modulus and private exponent var rsaprkey = new Key(); rsaprkey.setType(Key.PRIVATE); rsaprkey.setComponent(Key.MODULUS, new ByteString("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", HEX)); rsaprkey.setComponent(Key.EXPONENT, new ByteString("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", HEX)); // Make RSA public key from modulus and public exponent var rsapukey = new Key(); rsapukey.setType(Key.PUBLIC); rsapukey.setComponent(Key.MODULUS, new ByteString("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", HEX)); rsapukey.setComponent(Key.EXPONENT, new ByteString("11", HEX)); var inp = new ByteString("26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", HEX); assert(inp.length == 64); var cipher = crypto.encrypt(rsaprkey, Crypto.RSA, inp); print(cipher); var plain = crypto.decrypt(rsapukey, Crypto.RSA, cipher); print(plain); assert(plain.equals(inp)); // RSA encrypt with OAEP padding var inp = new ByteString("Message", ASCII); var cipher = crypto.encrypt(rsapukey, Crypto.RSA_OAEP, inp); print(cipher); var plain = crypto.decrypt(rsaprkey, Crypto.RSA, cipher); print("Decrypted OAEP block:"); print(plain); assert(plain.byteAt(0) == 0); var plain = crypto.decrypt(rsaprkey, Crypto.RSA_OAEP, cipher); assert(plain.equals(inp)); //RSA encrypt with PKCS#1 V1.5 padding var inp = new ByteString("Message", ASCII); var cipher = crypto.encrypt(rsapukey, Crypto.RSA_PKCS1, inp); print(cipher); var plain = crypto.decrypt(rsaprkey, Crypto.RSA, cipher); print("Decrypted PKCS#1 V1.5 block:"); print(plain); assert(plain.byteAt(0) == 0); assert(plain.byteAt(1) == 2); var plain = crypto.decrypt(rsaprkey, Crypto.RSA_PKCS1, cipher); assert(plain.equals(inp)); // Encrypt and decrypt with RSA primitive using ISO 9796-2 (DINSIG) variant that // ensures that the numeric value of the output message is less than half of the // modulus var inp = new ByteString("260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BC", HEX); assert(inp.length == 64); var cipher = crypto.encrypt(rsaprkey, Crypto.RSA_ISO9796_2, inp); print(cipher); var plain = crypto.decrypt(rsapukey, Crypto.RSA_ISO9796_2, cipher); assert(plain.equals(inp)); // Make RSA private key from CRT components stored in key profile var rsaprkey = new Key("profiles/kp_rsa_private_crt.xml"); // Make RSA public key from modulus and public exponent stored in key profile var rsapukey = new Key("profiles/kp_rsa_public.xml"); var inp = new ByteString("26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", HEX); assert(inp.length == 64); var cipher = crypto.encrypt(rsaprkey, Crypto.RSA, inp); print(cipher); var plain = crypto.decrypt(rsapukey, Crypto.RSA, cipher); print(plain); assert(plain.equals(inp)); decrypt()PrototypeByteString decrypt(Key key, Number mech, ByteString data) ByteString decrypt(Key key, Number mech, ByteString data, ByteString iv) DescriptionDecrypt the cipher in data using the algorithm defined by mech and the specified key. If the algorithm requires an initialisation vector, then the additional argument iv must be specified (DES_CBC, AES_CBC or AES_CTR). The Crypto.RSA mechanism performs a plain RSA decrypt operation with no encoding format. The Crypto.RSA_ISO9796_2 mechanism performs a plain RSA decrypt operation with no encoding format but according to ISO 9697-2. The Crypto.PKCS1 mechanism performs a RSA decrypt operation with PKCS1 V1.5 encoding format. The Crypto.OAEP_XXX mechanism performs a RSA decrypt operation with PKCS1 V2.1 OEAP encoding format using the selected message digest algorithm and MGF1. This method can also be used to perform an ECDH or an ECDHC with cofactor primitive using a private EC key. The method treats the data as x and y coordinate of the EC public key from the sending party. The Crypto.ECDH method return as result the x coordinate of the multiplication of the private key value d with the public point Q (result = xof(d * q)) The Crypto.ECDHC method returns as result the x coordinate of the multiplication of the private key value d with the cofactor h and the public point Q (result = xof(d * h * q)). The cofactor is a parameter of the curve. The Crypto.ECDHP method returns as result the concatenation of the x and y coordinate of the multiplication of the private key value d with the public point Q (result = d * h * q). This method is a non-standard variant, only available with the default BouncyCastle crypto provider. The ECDH decryption is a basic building block for cipher operations based on ECC. The result of the decrypt operation is a common secret, which can be either used directly as secret key or used as input to a key derivation process. Arguments
Return
Exceptions
Example// See encrypt() for a complete example using DES and RSA // ECDH Generating a shared secret between Bob and Alice to exchange protected messages var pubKeyBob = new Key(); pubKeyBob.setType(Key.PUBLIC); pubKeyBob.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); var priKeyBob = new Key(); priKeyBob.setType(Key.PRIVATE); priKeyBob.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); crypto.generateKeyPair(Crypto.EC, pubKeyBob, priKeyBob); var pubKeyAlice = new Key(); pubKeyAlice.setType(Key.PUBLIC); pubKeyAlice.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); var priKeyAlice = new Key(); priKeyAlice.setType(Key.PRIVATE); priKeyAlice.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); crypto.generateKeyPair(Crypto.EC, pubKeyAlice, priKeyAlice); var inputBob = pubKeyBob.getComponent(Key.ECC_QX).concat(pubKeyBob.getComponent(Key.ECC_QY)); var inputAlice = pubKeyAlice.getComponent(Key.ECC_QX).concat(pubKeyAlice.getComponent(Key.ECC_QY)); var secretAlice = crypto.decrypt(priKeyAlice, Crypto.ECDH, inputBob); print(secretAlice); var secretBob = crypto.decrypt(priKeyBob, Crypto.ECDH, inputAlice); print(secretBob); assert(secretBob.equals(secretAlice)); var secretAlice = crypto.decrypt(priKeyAlice, Crypto.ECDHC, inputBob); print(secretAlice); var secretBob = crypto.decrypt(priKeyBob, Crypto.ECDHC, inputAlice); print(secretBob); assert(secretBob.equals(secretAlice)); var secretAlice = crypto.decrypt(priKeyAlice, Crypto.ECDHP, inputBob); print(secretAlice); var secretBob = crypto.decrypt(priKeyBob, Crypto.ECDHP, inputAlice); print(secretBob); assert(secretBob.equals(secretAlice)); sign()PrototypeByteString sign(Key key, Number mech, ByteString data) ByteString sign(Key key, Number mech, ByteString data, ByteString iv) DescriptionSign the data provided using the mechanism and key specified. If the algorithms requires an initialisation vector, then it can be provided in the iv argument. When the Crypto.RSA argument is supplied, then RSA with SHA-1 and PKCS#1 V1.5 encoding is used as signature algorithm. Crypto.RSA has the same effect as Crypto.RSA_SHA1. When the Crypto.ECDSA argument is supplied, then ECDSA without a hash is used, i.e. the hash value must be provided as input. A signature created using ECDSA is encoded in an ASN1 SEQUENCE object containing an INTEGER object r and s. See RFC3279 for details. A method to convert a TLV encoded ECDSA signature into a binary concatenation of the x and y coordinate is provided in the tools/eccutils.js script. Arguments
Return
Exceptions
Example// Instantiate crypto service var crypto = new Crypto(); // Define 3 different single DES key values var key1 = new ByteString("7CA110454A1A6E57", HEX); var key2 = new ByteString("0131D9619DC1376E", HEX); var key3 = new ByteString("9DC1376E0131D961", HEX); var plain = new ByteString("Hello World !!!!", ASCII); var cipher; var result; // Create three single DES keys, a double DES key and a triple DES key var deskey1 = new Key(); deskey1.setComponent(Key.DES, key1); var deskey2 = new Key(); deskey2.setComponent(Key.DES, key2); var deskey3 = new Key(); deskey3.setComponent(Key.DES, key3); var des2key = new Key(); des2key.setComponent(Key.DES, key1.concat(key2)); var des3key = new Key(); des3key.setComponent(Key.DES, key1.concat(key2).concat(key3)); // Triple DES MAC cipher = crypto.encrypt(des3key, Crypto.DES_ECB, plain.bytes(0, 8)); cipher = cipher.xor(plain.bytes(8, 8)); cipher = crypto.encrypt(des3key, Crypto.DES_ECB, cipher); result = crypto.sign(des3key, Crypto.DES_MAC, plain); assert(result.equals(cipher)); // Triple DES MAC according to EMV (aka Retail MAC) cipher = crypto.encrypt(deskey1, Crypto.DES_ECB, plain.bytes(0, 8)); cipher = cipher.xor(plain.bytes(8, 8)); cipher = crypto.encrypt(deskey1, Crypto.DES_ECB, cipher); cipher = crypto.decrypt(deskey2, Crypto.DES_ECB, cipher); cipher = crypto.encrypt(deskey1, Crypto.DES_ECB, cipher); result = crypto.sign(des2key, Crypto.DES_MAC_EMV, plain); assert(result.equals(cipher)); // AES MAC // Make key a 128 bit AES key var key = new Key(); key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f", HEX)); var plain = new ByteString("01234567890123456789012345678901", ASCII); var cipher = crypto.encrypt(key, Crypto.AES_ECB, plain.bytes(0, 16)); cipher = cipher.xor(plain.bytes(16, 16)); var cipher = crypto.encrypt(key, Crypto.AES_ECB, cipher); result = crypto.sign(key, Crypto.AES_MAC, plain); assert(result.equals(cipher)); //AES CMAC //Make key a 128 bit AES key var key = new Key(); key.setComponent(Key.AES, new ByteString("2b7e151628aed2a6abf7158809cf4f3c", HEX)); var plain = new ByteString("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411", HEX); var mac = crypto.sign(key, Crypto.AES_CMAC, plain); var ref = new ByteString("dfa66747de9ae63030ca32611497c827", HEX); assert(ref.equals(mac)); // RSA with SHA-1 var rsaprkey = new Key("profiles/kp_rsa_private_crt.xml"); var rsapukey = new Key("profiles/kp_rsa_public.xml"); var message = new ByteString("Hello World !", ASCII); var signature = crypto.sign(rsaprkey, Crypto.RSA, message); print("Plain PKCS#1 V1.5 = " + crypto.decrypt(rsapukey, Crypto.RSA, signature)); assert(crypto.verify(rsapukey, Crypto.RSA, message, signature)); // RSA with SHA-224 var signature = crypto.sign(rsaprkey, Crypto.RSA_SHA224, message); print("Plain PKCS#1 V1.5 = " + crypto.decrypt(rsapukey, Crypto.RSA, signature)); assert(crypto.verify(rsapukey, Crypto.RSA_SHA224, message, signature)); // RSA with SHA-256 var signature = crypto.sign(rsaprkey, Crypto.RSA_SHA256, message); print("Plain PKCS#1 V1.5 = " + crypto.decrypt(rsapukey, Crypto.RSA, signature)); assert(crypto.verify(rsapukey, Crypto.RSA_SHA256, message, signature)); //RSA with SHA-1 and PSS var signature = crypto.sign(rsaprkey, Crypto.RSA_PSS_SHA1, message); print("Plain PSS = " + crypto.decrypt(rsapukey, Crypto.RSA, signature)); assert(crypto.verify(rsapukey, Crypto.RSA_PSS_SHA1, message, signature)); //Create empty public key object and set size var rsapukey = new Key(); rsapukey.setType(Key.PUBLIC); rsapukey.setSize(1024); // Create empty private key object and set size var rsaprkey = new Key(); rsaprkey.setType(Key.PRIVATE); // Generate key pair crypto.generateKeyPair(Crypto.RSA, rsapukey, rsaprkey); //RSA with SHA-256 and PSS var signature = crypto.sign(rsaprkey, Crypto.RSA_PSS_SHA256, message); print("Plain PSS = " + crypto.decrypt(rsapukey, Crypto.RSA, signature)); assert(crypto.verify(rsapukey, Crypto.RSA_PSS_SHA256, message, signature)); // ECDSA Fp with SHA-1 var eccprkey = new Key("profiles/kp_ec_private.xml"); var eccpukey = new Key("profiles/kp_ec_public.xml"); var message = new ByteString("Hello World !", ASCII); var signature = crypto.sign(eccprkey, Crypto.ECDSA_SHA1, message); assert(crypto.verify(eccpukey, Crypto.ECDSA_SHA1, message, signature)); // ECDSA F2m with SHA-1 var eccprkey = new Key("profiles/kp_ec_f2m_private.xml"); var eccpukey = new Key("profiles/kp_ec_f2m_public.xml"); var message = new ByteString("Hello World !", ASCII); var signature = crypto.sign(eccprkey, Crypto.ECDSA_SHA1, message); assert(crypto.verify(eccpukey, Crypto.ECDSA_SHA1, message, signature)); // see Crypto.generateKeyPair for longer ECC keys verify()PrototypeBoolean verify(Key key, Number mech, ByteString data, ByteString signature) Boolean verify(Key key, Number mech, ByteString data, ByteString signature, ByteString iv) DescriptionVerify the signature applied to data with the mechanism and key specified For ECDSA the signature must be TLV encoded as defined in RFC3279. A method to convert a ECDSA signature encoded as binary concatenation of the x and y coordinate into the TLV format is provided in the tools/eccutils.js script. Arguments
Return
Exceptions
Example// Instantiate crypto service var crypto = new Crypto(); // Define 3 different single DES key values var key1 = new ByteString("7CA110454A1A6E57", HEX); var key2 = new ByteString("0131D9619DC1376E", HEX); var key3 = new ByteString("9DC1376E0131D961", HEX); var plain = new ByteString("Hello World !!!!", ASCII); var cipher; var result; // Create three single DES keys, a double DES key and a triple DES key var des1key = new Key(); des1key.setComponent(Key.DES, key1); var des2key = new Key(); des2key.setComponent(Key.DES, key1.concat(key2)); var des3key = new Key(); des3key.setComponent(Key.DES, key1.concat(key2).concat(key3)); // Single DES MAC result = crypto.sign(des1key, Crypto.DES_MAC, plain); var ok = crypto.verify(des1key, Crypto.DES_MAC, plain, result); assert(ok); // Triple DES MAC result = crypto.sign(des3key, Crypto.DES_MAC, plain); var ok = crypto.verify(des3key, Crypto.DES_MAC, plain, result); assert(ok); // Triple DES MAC according to EMV (aka Retail MAC) result = crypto.sign(des2key, Crypto.DES_MAC_EMV, plain); var ok = crypto.verify(des2key, Crypto.DES_MAC_EMV, plain, result); assert(ok); // AES MAC // Make key a 128 bit AES key var key = new Key(); key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f", HEX)); var plain = new ByteString("01234567890123456789012345678901", ASCII); result = crypto.sign(key, Crypto.AES_MAC, plain); var ok = crypto.verify(key, Crypto.AES_MAC, plain, result); assert(ok); //AES CMAC //Make key a 128 bit AES key var key = new Key(); key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f", HEX)); var plain = new ByteString("01234567890123456789012345678901", ASCII); result = crypto.sign(key, Crypto.AES_CMAC, plain); var ok = crypto.verify(key, Crypto.AES_CMAC, plain, result); assert(ok); // RSA var cert = new X509("root.cer"); var ncert = cert.getNative(); var message = ncert.getTBSCertificate(); var signature = ncert.getSignature(); var key = cert.getPublicKey(); assert(crypto.verify(key, Crypto.RSA, message, signature)); // ECDSA var cert = new X509("ecdsacert.cer"); var key = cert.getPublicKey(); var message = new ByteString("Hello World", ASCII); // Be carefull if the most significant bit of r or s is 1. In that case you need // to add a 00 to prevent interpretation as negative integer var r = new ByteString("06CF31FCE556DC74F7B0B3061E47300CC11B3F5BFD01976A", HEX); var s = new ByteString("33F8D70EF472EEC8489CAA705837FA5F0156BF70CFD371FD", HEX); var signature = new ASN1(ASN1.SEQUENCE); signature.add(new ASN1(ASN1.INTEGER, r)); signature.add(new ASN1(ASN1.INTEGER, s)); assert(crypto.verify(key, Crypto.ECDSA_SHA1, message, signature.getBytes())); deriveKey()Prototypevoid deriveKey (Key masterKey, Number mech, ByteString data, Key derivedKey) DescriptionDerive key from a master key using the mechanism specified and data for diversification. The resulting DES key is parity adjusted, so that the number of 1 bits in each byte of the key value is odd. This method can be used to calculate a public key (point) by multiplying the point with a skalar value and adding a second point (EC_MULTIPLY_ADD). This method is used in the PACE protocol to determine a temporary generator point using the formular G' = s * G + P. The parameter G is the point from the masterKey, the point P is provided by the public key value in derivedKey and the skalar value s is provided in the argument data. The result is stored as public key value in derivedKey. If the public point P is undefined, then only the skalar multiplication is performed. If the argument data is null, then only the point addition is performed. Arguments
Return
Exceptions
Example// Instantiate crypto service var crypto = new Crypto(); // Create a single DES key, a double DES key and a triple DES key var des1key = new Key("profiles/kp_single_des_1.xml"); var des2key = new Key("profiles/kp_double_des.xml"); var des3key = new Key("profiles/kp_triple_des.xml"); // Define derivation parameter var dpara8 = new ByteString("0102030405060708", HEX); var dpara16 = new ByteString("01020304050607081020304050607080", HEX); var dpara24 = new ByteString("010203040506070810203040506070801122334455667788", HEX); var derivedKey = new Key(); var reference; // Derive a single DES key crypto.deriveKey(des1key, Crypto.DES_ECB, dpara8, derivedKey); reference = crypto.encrypt(des1key, Crypto.DES_ECB, dpara8); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a double DES key crypto.deriveKey(des1key, Crypto.DES_ECB, dpara16, derivedKey); reference = crypto.encrypt(des1key, Crypto.DES_ECB, dpara16); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a triple DES key crypto.deriveKey(des1key, Crypto.DES_ECB, dpara24, derivedKey); reference = crypto.encrypt(des1key, Crypto.DES_ECB, dpara24); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a single DES key crypto.deriveKey(des2key, Crypto.DES_ECB, dpara8, derivedKey); reference = crypto.encrypt(des2key, Crypto.DES_ECB, dpara8); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a double DES key crypto.deriveKey(des2key, Crypto.DES_ECB, dpara16, derivedKey); reference = crypto.encrypt(des2key, Crypto.DES_ECB, dpara16); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a triple DES key crypto.deriveKey(des2key, Crypto.DES_ECB, dpara24, derivedKey); reference = crypto.encrypt(des2key, Crypto.DES_ECB, dpara24); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a single DES key crypto.deriveKey(des3key, Crypto.DES_ECB, dpara8, derivedKey); reference = crypto.encrypt(des3key, Crypto.DES_ECB, dpara8); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a double DES key crypto.deriveKey(des3key, Crypto.DES_ECB, dpara16, derivedKey); reference = crypto.encrypt(des3key, Crypto.DES_ECB, dpara16); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a triple DES key crypto.deriveKey(des3key, Crypto.DES_ECB, dpara24, derivedKey); reference = crypto.encrypt(des3key, Crypto.DES_ECB, dpara24); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); var iv = new ByteString("0000000000000000", HEX); // Derive a single DES key crypto.deriveKey(des1key, Crypto.DES_CBC, dpara8, derivedKey); reference = crypto.encrypt(des1key, Crypto.DES_CBC, dpara8, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a double DES key crypto.deriveKey(des1key, Crypto.DES_CBC, dpara16, derivedKey); reference = crypto.encrypt(des1key, Crypto.DES_CBC, dpara16, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a triple DES key crypto.deriveKey(des1key, Crypto.DES_CBC, dpara24, derivedKey); reference = crypto.encrypt(des1key, Crypto.DES_CBC, dpara24, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a single DES key crypto.deriveKey(des2key, Crypto.DES_CBC, dpara8, derivedKey); reference = crypto.encrypt(des2key, Crypto.DES_CBC, dpara8, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a double DES key crypto.deriveKey(des2key, Crypto.DES_CBC, dpara16, derivedKey); reference = crypto.encrypt(des2key, Crypto.DES_CBC, dpara16, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a triple DES key crypto.deriveKey(des2key, Crypto.DES_CBC, dpara24, derivedKey); reference = crypto.encrypt(des2key, Crypto.DES_CBC, dpara24, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a single DES key crypto.deriveKey(des3key, Crypto.DES_CBC, dpara8, derivedKey); reference = crypto.encrypt(des3key, Crypto.DES_CBC, dpara8, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a double DES key crypto.deriveKey(des3key, Crypto.DES_CBC, dpara16, derivedKey); reference = crypto.encrypt(des3key, Crypto.DES_CBC, dpara16, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Derive a triple DES key crypto.deriveKey(des3key, Crypto.DES_CBC, dpara24, derivedKey); reference = crypto.encrypt(des3key, Crypto.DES_CBC, dpara24, iv); assert(keyequals(derivedKey.getComponent(Key.DES), reference)); // Calculate a new point by multiplying G with skalar s and adding P. // This method is used to implement PACE as defined by the Extended Access Control 2.x specification var P = new Key(); P.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.36.3.3.2.8.1.1.5", OID)); P.setComponent(Key.ECC_QX, new ByteString("A99D861875FDCAF2406B6CE4423C1FE2EB4396A8636CF039C723DDEE", HEX)); P.setComponent(Key.ECC_QY, new ByteString("634A17EA9EC0DC8611EF51CDF46E8247C64A2B9F8ECFCE53B690ADC0", HEX)); var G = new Key(); G.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.36.3.3.2.8.1.1.5", OID)); G.setComponent(Key.ECC_QX, P.getComponent(Key.ECC_GX)); G.setComponent(Key.ECC_QY, P.getComponent(Key.ECC_GY)); var s = new ByteString("3924D2D1E31CE13C", HEX); // Calculate G' = s * G + P crypto.deriveKey(G, Crypto.EC_MULTIPLY_ADD, s, P); // This method does not change the generator point directly, but the public key point in the // derived key. For PACE the public key point ECC_QX/Y must be copied to ECC_GX/Y ! assert(P.getComponent(Key.ECC_QX).toString(HEX) == "992042B9D17CBDFA5915EAE4292E62A3F6582071622371F47C2C717E"); assert(P.getComponent(Key.ECC_QY).toString(HEX) == "16FC907BD3D87C7F45F56533DE33909A3A1D1E25487615284BC741E7"); var G1 = new Key(); G1.setType(Key.PUBLIC); G1.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.36.3.3.2.8.1.1.5", OID)); var G = new Key(); G.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.36.3.3.2.8.1.1.5", OID)); G.setComponent(Key.ECC_QX, P.getComponent(Key.ECC_GX)); G.setComponent(Key.ECC_QY, P.getComponent(Key.ECC_GY)); var s = new ByteString("3924D2D1E31CE13C", HEX); // Calculate G'' = s * G crypto.deriveKey(G, Crypto.EC_MULTIPLY_ADD, s, G1); var P = new Key(); P.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.36.3.3.2.8.1.1.5", OID)); P.setComponent(Key.ECC_QX, new ByteString("A99D861875FDCAF2406B6CE4423C1FE2EB4396A8636CF039C723DDEE", HEX)); P.setComponent(Key.ECC_QY, new ByteString("634A17EA9EC0DC8611EF51CDF46E8247C64A2B9F8ECFCE53B690ADC0", HEX)); //Calculate G'' = G'' + P crypto.deriveKey(G1, Crypto.EC_MULTIPLY_ADD, null, P); assert(P.getComponent(Key.ECC_QX).toString(HEX) == "992042B9D17CBDFA5915EAE4292E62A3F6582071622371F47C2C717E"); assert(P.getComponent(Key.ECC_QY).toString(HEX) == "16FC907BD3D87C7F45F56533DE33909A3A1D1E25487615284BC741E7"); digest()PrototypeByteString digest(Number mech, ByteString data) DescriptionCalculate message digest for data using hash algorithm specified in argument mech.Arguments
Return
Exceptions
Examplevar message = new ByteString("Hello World", ASCII); var hash = crypto.digest(Crypto.SHA_1, message); print("SHA1: " + hash); var hash = crypto.digest(Crypto.MD5, message); print("MD5: " + hash); var message = new ByteString("", HEX); var ref = new ByteString("da39a3ee5e6b4b0d3255bfef95601890afd80709", HEX); var hash = crypto.digest(Crypto.SHA_1, message); assert(ref.equals(hash)); var message = new ByteString("61", HEX); var ref = new ByteString("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", HEX); var hash = crypto.digest(Crypto.SHA_1, message); assert(ref.equals(hash)); var message = new ByteString("616263", HEX); var ref = new ByteString("a9993e364706816aba3e25717850c26c9cd0d89d", HEX); var hash = crypto.digest(Crypto.SHA_1, message); assert(ref.equals(hash)); var message = new ByteString("6162636465666768696a6b6c6d6e6f707172737475767778797a", HEX); var ref = new ByteString("32d10c7b8cf96570ca04ce37f2a19d84240d3a89", HEX); var hash = crypto.digest(Crypto.SHA_1, message); assert(ref.equals(hash)); var message = new ByteString("616263", HEX); var ref = new ByteString("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", HEX); var hash = crypto.digest(Crypto.SHA_224, message); assert(ref.equals(hash)); var message = new ByteString("616263", HEX); var ref = new ByteString("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", HEX); var hash = crypto.digest(Crypto.SHA_256, message); assert(ref.equals(hash)); var message = new ByteString("616263", HEX); var ref = new ByteString("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", HEX); var hash = crypto.digest(Crypto.SHA_384, message); assert(ref.equals(hash)); var message = new ByteString("616263", HEX); var ref = new ByteString("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", HEX); var hash = crypto.digest(Crypto.SHA_512, message); assert(ref.equals(hash)); var message = new ByteString("", HEX); var ref = new ByteString("d41d8cd98f00b204e9800998ecf8427e", HEX); var hash = crypto.digest(Crypto.MD5, message); assert(ref.equals(hash)); var message = new ByteString("61", HEX); var ref = new ByteString("0cc175b9c0f1b6a831c399e269772661", HEX); var hash = crypto.digest(Crypto.MD5, message); assert(ref.equals(hash)); var message = new ByteString("616263", HEX); var ref = new ByteString("900150983cd24fb0d6963f7d28e17f72", HEX); var hash = crypto.digest(Crypto.MD5, message); assert(ref.equals(hash)); var message = new ByteString("6162636465666768696a6b6c6d6e6f707172737475767778797a", HEX); var ref = new ByteString("c3fcd3d76192e4007dfb496cca67e13b", HEX); var hash = crypto.digest(Crypto.MD5, message); assert(ref.equals(hash)); generateKeyPair()PrototypeVoid generateKeyPair(Number mech, Key pubKey, Key priKey) DescriptionGenerate an asymmetric key pair according to the specification from the public key object. For RSA key, the key size must be defined using the Key.setSize() method. For EC keys, the curve parameter must be set using the setComponent() method. Arguments
Return
Exceptions
Example// RSA Example - Generate a 1024 bit RSA key pair // Create empty public key object and set size var pubKey = new Key(); pubKey.setType(Key.PUBLIC); pubKey.setSize(1024); // Create empty private key object and set size var priKey = new Key(); priKey.setType(Key.PRIVATE); // Generate key pair crypto.generateKeyPair(Crypto.RSA, pubKey, priKey); // Extract key components... var modulus = pubKey.getComponent(Key.MODULUS); print("RSA Modulus:"); print(modulus); var publicexponent = pubKey.getComponent(Key.EXPONENT); print("RSA Public Exponent:"); print(publicexponent); print("CRT prime P"); var crt_p = priKey.getComponent(Key.CRT_P); print(crt_p); print("CRT prime Q"); var crt_q = priKey.getComponent(Key.CRT_Q); print(crt_q); print("CRT prime exponent P"); var crt_dp = priKey.getComponent(Key.CRT_DP1); print(crt_dp); print("CRT prime exponent Q"); var crt_dq = priKey.getComponent(Key.CRT_DQ1); print(crt_dq); print("CRT coefficient pq"); var crt_pq = priKey.getComponent(Key.CRT_PQ); print(crt_pq); // ... and reassemble in newly created key var pubKey = new Key(); pubKey.setType(Key.PUBLIC); pubKey.setComponent(Key.MODULUS, modulus); pubKey.setComponent(Key.EXPONENT, publicexponent); var priKey = new Key(); priKey.setType(Key.PRIVATE); priKey.setComponent(Key.CRT_P, crt_p); priKey.setComponent(Key.CRT_Q, crt_q); priKey.setComponent(Key.CRT_DP1, crt_dp); priKey.setComponent(Key.CRT_DQ1, crt_dq); priKey.setComponent(Key.CRT_PQ, crt_pq); // Verify that keys still work var message = new ByteString("Hello World", ASCII); var cryptogram = crypto.sign(priKey, Crypto.RSA, message); assert(crypto.verify(pubKey, Crypto.RSA, message, cryptogram)); // ECC Example - Generate a 192 bit key pair over the prime192v1 curve // Create empty public key object var pubKey = new Key(); pubKey.setType(Key.PUBLIC); // Select prime192v1 curve using it's object identifier pubKey.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); // Print out the curve parameter selected print("Curve Fp:"); print(pubKey.getComponent(Key.ECC_P)); print("Curve A:"); print(pubKey.getComponent(Key.ECC_A)); print("Curve B:"); print(pubKey.getComponent(Key.ECC_B)); print("Parameter Gx:"); print(pubKey.getComponent(Key.ECC_GX)); print("Parameter Gy:"); print(pubKey.getComponent(Key.ECC_GY)); print("Parameter N:"); print(pubKey.getComponent(Key.ECC_N)); print("Parameter H:"); print(pubKey.getComponent(Key.ECC_H)); // Create empty private key object var priKey = new Key(); priKey.setType(Key.PRIVATE); // Generate key pair crypto.generateKeyPair(Crypto.EC, pubKey, priKey); // Extract and print private and public key values print("Public Key Qx:"); var qx = pubKey.getComponent(Key.ECC_QX); assert(qx.length == 24); print(qx.toString(HEX)); var qy = pubKey.getComponent(Key.ECC_QY); assert(qy.length == 24); print("Public Key Qy:"); print(qy.toString(HEX)); var d = priKey.getComponent(Key.ECC_D); print("Private Key D:"); print(d.toString(HEX)); // Reassemble keys var pubKey = new Key(); pubKey.setType(Key.PUBLIC); pubKey.setComponent(Key.ECC_QX, qx); pubKey.setComponent(Key.ECC_QY, qy); pubKey.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); var priKey = new Key(); priKey.setComponent(Key.ECC_D, d); priKey.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID)); // Test keys to verify integrity var message = new ByteString("Hello World", ASCII); var cryptogram = crypto.sign(priKey, Crypto.ECDSA_SHA1, message); assert(crypto.verify(pubKey, Crypto.ECDSA_SHA1, message, cryptogram)); // ECC Example - Generate a 571 bit key pair over the secp521r1 curve // Create empty public key object var pubKey = new Key(); pubKey.setType(Key.PUBLIC); // Select secp521r1 curve using it's object identifier pubKey.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.132.0.35", OID)); // Print out the curve parameter selected print("Curve P:"); print(pubKey.getComponent(Key.ECC_P)); print("Curve A:"); print(pubKey.getComponent(Key.ECC_A)); print("Curve B:"); print(pubKey.getComponent(Key.ECC_B)); print("Parameter Gx:"); print(pubKey.getComponent(Key.ECC_GX)); print("Parameter Gy:"); print(pubKey.getComponent(Key.ECC_GY)); print("Parameter N:"); print(pubKey.getComponent(Key.ECC_N)); print("Parameter H:"); print(pubKey.getComponent(Key.ECC_H)); // Create empty private key object var priKey = new Key(); priKey.setType(Key.PRIVATE); // Generate key pair crypto.generateKeyPair(Crypto.EC, pubKey, priKey); // Extract and print private and public key values print("Public Key Qx:"); var qx = pubKey.getComponent(Key.ECC_QX); assert(qx.length == 66); print(qx.toString(HEX)); var qy = pubKey.getComponent(Key.ECC_QY); assert(qy.length == 66); print("Public Key Qy:"); print(qy.toString(HEX)); var d = priKey.getComponent(Key.ECC_D); print("Private Key D:"); print(d.toString(HEX)); // Reassemble keys var pubKey = new Key(); pubKey.setType(Key.PUBLIC); pubKey.setComponent(Key.ECC_QX, qx); pubKey.setComponent(Key.ECC_QY, qy); pubKey.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.132.0.35", OID)); var priKey = new Key(); priKey.setComponent(Key.ECC_D, d); priKey.setComponent(Key.ECC_CURVE_OID, new ByteString("1.3.132.0.35", OID)); // Test keys to verify integrity var message = new ByteString("Hello World", ASCII); var cryptogram = crypto.sign(priKey, Crypto.ECDSA_SHA512, message); assert(crypto.verify(pubKey, Crypto.ECDSA_SHA512, message, cryptogram)); generateRandom()PrototypeByteString generateRandom(Number length) DescriptionGenerate a ByteString of given length with random dataArguments
Return
Exceptions
Examplevar val1 = crypto.generateRandom(10); assert(val1.length == 10); var val2 = crypto.generateRandom(10); assert(val2.length == 10); assert(val1 != val2); © Copyright 2003 - 2010 CardContact Software & System Consulting, Minden, Germany |