Public key encryption technology requires a space to store digital certificates and private keys. By storing the keys and certificates into a file (called KeyStore), Java Security Architecture implements an independent encryption technology.
Microsoft Windows stores keys and certificates into a Windows registry and file system. That is to say, users who run secure Java programs on a Windows system must enter and output keys and certificates between Java and Microsoft's keys and certificates. Good news is that you can "kid" Java applications use Microsoft's certificates and key libraries through Microsoft local functions.
By combining your Java application with the Windows key / certificate library, although you sacrifice the platform independence, you get four benefits: reduce the cost of management and support, more convenient for users to use, better certificate undo Check, and better keys and certificate management tools.
A Java program must implement integration with Windows encryption through four different classes: • TrustManager Provider: Use this class to implement integration with the Windows certificate library and implement security policies. · KeyManager Provider: Use this class to implement integration with the Windows private key library. · RSA Signature Provider: Digital Signature Need to access the private key library. If the Java program cannot read a private key (for example, if the private key is on a encrypted smart card), then the signature operation must be performed in Windows. · RSA Cipher Provider: Decryption RSA encrypted data (such as the key to the encryption sleeve protocol layer (SSL) symmetrical key) Need to access the private key. If the Java program cannot read a private key (for example, if the private key is on a cryptive smart card), then the RSA decryption operation must be done in Windows.
I will tell the usage of TrustManager Provider, KeyManager Provider, RSA Signature Provider, and RSA Cipher Provider integrated with Windows platform. TrustManager and KeyManager allow you to build a running Windows supported Java Secure Socket Extension (JSSE) application. JSSE Example Program - EchoServer and EchoClient can prove this. You cannot overwrite the built-in RSA Cipher Provider of JSSE, so only when the private key can be output from the Windows key library, the JSSE application can run.
If you are writing a Java app that uses RSA signatures or RSA encryption, you can use the RSA Signature Provider and Cipher Provider supported by Windows. This doesn't need to output private keys from the Windows key library. For other three providers, you can use each one alone.
This code is developed with beta version JDK 1.4.0-RC, which is very stable. However, we intend to use the code as a framework for further development. Before using the code for the production environment, you should improve the exception handling, confident that there is no memory leak in the local code and reduces the exposure of the key to the smallest. For test code, you need an RSA digital certificate. You can get a temporary certificate from the Verisign website www.verisign.com/client/enrollment, the validity period is 60 days. For details, please follow the guidelines on this site. Do not select boxes marked as "Protect Your Private Key". Because this box is not selected, your private key can be output.
The following preliminary test of the four codes provided by: MSTrustMgrProvider.install (); MSKeyMgrProvider.install (); MSRSASignProvider.install (); MSRSACipherProvider.install (); kmf = KeyManagerFactory.getInstance ( "MSKMF"); tmf = TrustManagerFactory. GetInstance ("MSTMF"); cipher cipher = copher.getInstance ("RSA / ECB / PKCS1PADDING"); Signature RSA = Signature.GetInstance ("Sha1withRSA");
All four providers call 10 local Microsoft functions: · MsgetCacerts () returns a certificate issued by the Certificate Authority (CA) from the Microsoft Certificate of Authority (CA). • If a certificate is not revoked, MSVERIFYCERTREVOCATION () returns True. · MsgetPrivateKey () returns a private key for a specific alias (Alias). (An alias mentioned here is an identity with an RSA private key and certificate.) The key is output from the Microsoft key library. · MsgetCert () returns a certificate from the Microsoft certificate library for a specific alias. · MsgetaliaSES () Returns a group of alias (name with the identity of the private key). Each private key in the Microsoft Key Branch has an alias. · MSRSASIGNHASH () Returns the RSA signature of Hashed Data. · MSRSADecrypt () uses the RSA algorithm to decrypt a previously encrypted data block. · MsrsaEncrypt () uses Microsoft RSA Provider to encrypt a data block. · MSRSAGETKEYSIZE () Returns the RSA key size of a key in the Microsoft Key Branch. · MsgetCRL () Download a certificate revocation list (CRL) to the Microsoft Internet Cache.
All of these functions are included in the source file written in C-language code written in C-language code. This code can run on Windows 98 / NT4 / 2000 / XP. Public key encryption algorithm
There are two purposes: encryption and digital signature. Public key encryption uses a key (or a pair of keys) containing two parts: a private key and a public key. The public key has the start and termination date, a serial number, an identity (called Subject Distinguished Name), and a CA signature (see List 1). RSA is the most common public key encryption algorithm.
Public key encryption uses a public key and a private key. A digital certificate (shown below) contains a signature of the public key, start and end date, a serial number, an identity, and a certificate authorization center (CA). Serial number: 6822 3C33 7945 3AC8 F8C5 398B 7469 94E1Signature algorithm: md5RSAIssuer:. CN = VeriSign Class 1 CA IndividualSubscriber-Persona Not Validated, OU = www.verisign.com/repository/RPA Incorp By Ref, LIAB.LTD (c). 98, OU = VERISIGN TRUST NETWORK, O = VERISIGN, Inc.valid from: Wednesday, May 30, 2001 7:00:00 PMValid to: Monday, July 30, 2001 6:59:59 PMSUBJECT: E = Boyter @ TXDirect. Net, CN = Brian Boyter, OU = Digital ID Class 1 ? Microsoft, Ou = Persona Not Validated, Ou = www.veriSign.com/repository/rpa incorp. by Ref., LIAB.LTD (C) 98, OU = VeriSign Trust Network, O = VeriSign, Inc.Public key: 3081 8902 8181 00BA B459 0F39 156E C69E C238 BFD0 401D DBB9 D207 DFA4 5DBD 09F3 5CE6 B5E6 C357 88DD 808B 0699 5F68 A2A4 6A8A 3B21 6D3D D0A1 1E5F DAB1 FB8E F835 F84F 849B 29A4 6943 8D59 0669 7C81 1D00 03B7 1A02 4E7A 8596 11BD 7CC4 07A3 D7E5 9FF6 5684 B853 04F0 0938 A11E 5218 F9AB F034 070D C8C4 6652 C19B 4C57 E435 EFDC 85D4 B269 07B7 0102 0301 0001Basic constraints: Subject Type = End Entity, Path Len gth Constraint = NoneCertificate policy: Policy Qualifier Id = CPS Qualifier: https: //www.verisign.com/CPSPolicy Qualifier Info: Organization = VeriSign, Inc., Notice Number = 1CRL Distribution Point Distribution Point Name: Full Name: URL = http : //crl.verisign.com/class1.crthumbprint Algorithm: Sha1thumbprint: 74A8 9F07 43AA 8FFC C4D5 AB09 3773 3AFF F7E7 DFFC
The encryption in the public key encryption is done with the public key, and the decryption is done with the private key. Public key encryption is complicated for a large number of encryption, but it is widely used to allocate keys. Key, or symmetric encryption algorithms, such as DES and RC4, typically used for a large number of encryption, but key plus algorithms require some confidential methods to exchange keys for a large amount of encrypted. One technology is to generate a random number, encrypt the random number with a public key encryption algorithm, and then encrypt the random number to the distal companion. The sender encrypts the random number with the public key of the remote companion. The recipient decrypts this random number with its own private key. Any third party intercepted the encrypted random number cannot decrypt the random number because he has no private key. In the digital signature, use the private key to complete the signature, with the public key to complete the confirmation. The signed file is usually handled by a hash algorithm. The hash algorithm is a one-way algorithm that reduces the size of the file. With the MD5 hash algorithm, the file is short to 16 bytes. Use the SHA1 hash algorithm, the file is simple to 20 bytes. Then, the file that has been handled by the hash algorithm is then encrypted with the documentary private key. Anyone can decrypt the hash file with a signature public key.
You must protect your private key very carefully. Windows stores private keys in a confusing form in a file system. A malicious invader can enter your computer and find your private key. Anyone who got your private key can be installed into you, and make a signed document in the case of you don't know. A method of protecting the private key is to use a encrypted smart card that stores a private key on the card. Using a encrypted smart card, the user can still perform public key encryption and signature activity, but no one - or even users - can read private keys. The smart card has an RSA encryption and signature processor, and only this RSA processor has the right to use private keys.
When an SSL server confirms the identity to an SSL client, the client must determine if the server is valid according to the following criteria: · The certificate must have a trust chain, and the root CA must be a client trust. · Server certificates, and all CA certificates in the trust chain must have a valid signature. Each certificate is signed by the more advanced CA, except for the root CA, it is signed your own certificate. · The current date and time must be within the validity period of the server certificate, and it is also within the validity period of all certificates in the trust chain. Each certificate has a validity period (a certificate that can be effectively used and the start date and time and the end date and time). · Each CA should manage and publish a CRL. The client must be able to get the CRS from each CA in the trust chain to see if a certificate of the server certificate or the subordinate CA has been revoked by the more advanced CA below. · Certificate must be available for its purpose. The purpose of the key is defined in the certificate. For example, the CA approved only one key for digital signatures cannot be used for SSL key exchange.
The Java security implementation is not confirmed in the environment, that is, it does not perform CRL processing. I will show you how to use Microsoft Windows's local encryption function to check the CRLS in the certificate trust chain to implement a TrustManager and KeyManager for Java.
TrustManager
Javax.net.ssl.x509trustManager has three ways, you can find in MSTRUSTMANAGERLMPL.JAVA: · getacceptedissuers () returns a set of certificates for all CASs in the Microsoft certificate library. CheckClientTrusted () Executes the server's security policy. · CheckServertRUSTED () Execute the security policy of the client.
A typical TCP network security policy is: • The client starts to connect. Suppose the client is only connected to the "secure" server. The client should ask the server to prove the identity to the client with a digital certificate. By confirming the server's certificate (trust chain, the signature is valid, the certificate is valid, the certificate is not revoked, and the certificate is approved for the RSA key exchange), and the client confirms the authenticity of the server. The client trusts the server through a valid certificate. · The server receives TCP connections from all clients, and some clients may be malicious. The server can ask the client to prove the identity to the server with a digital certificate. In that case, the client's identity can be confirmed and a variety of trust levels can also be implemented. If the server does not require a client to prove identity, the server should assume that all clients are malicious. You can see in CheckServertrusted (), which is easy to implement the client security policy. CheckServertrusted () Check the valid date and CRLs of the certificate in the trust chain. (I will explore the certificate undo processing later.) The checkclienttrusted () method is the same as checkservertrusted (). In general, this security policy is not enough for the server. A method of enhancing server security is required to request a client to demonstrate identity, only accept a certificate released by a specific CA (such as VeriSign CA), and verify the special field in the Subject Distinguished Name of the certificate (such as 0 = Sun.com). You can add this process to checkclienttrusted () only a few lines of Java code. You need to customize CheckClientTrusted () to implement your security policy (see List 2).
CheckClientTrusted () method Checks the valid date and CRLs of the certificate in the signature, trust chain. However, this security function is not enough for the server. You can enhance security policies by customizing CheckClientTrusted (). public void checkClientTrusted (X509Certificate chain []) {// DontKnowFlag indicates what to do if we're // not sure if the certificate is revoked // int DontKnowFlag = 0; // reject the cert // int DontKnowFlag = 1; / / accept the certint DontKnowFlag = 2; // ask the user // check for revoked certs in the cert chainif (com.boyter.mscrypto.MSValidCertificate.isCertChainValid (chain, DontKnowFlag)) return; // client cert is not trustedSystem.out .println ("Client Certificate Is Not Trusted - Aborting"); System.exit (2);
Java provides several classes associated with certification chain, and is further explained in Java Certification Path API Programmer's Guide. I have done experiments for them, and I finally decided not to use them, because I think they are too complicated. TrustManager has a third method getacceptedissuers (). This method returns a set of certificates for all CAS in the Microsoft certificate library. Microsoft stores these certificates in Registry; you can find them by launching the regedit program and viewing hkey_local_machine / software / microsoft / systemcertificates / root / certificates. The getacceptedissuers () method performs the local function CERTENUMCERTIFICATESLNSTORE () of Microsoft. The CA certificate is transmitted back to the Java method as a string of Base64-bit encoded string. Java.security.cert.certificateFactory converts Base64 encoded certificates to Java certificates.
Certificate revoke
There are two ways to undo the certificate: Online Certificate Status Protocol (OCSP) and CRL. OCSP (see RFC2560) did not have extensive support, so I only explored the CRLS used to confirm the undo status of a certificate. CAS regularly publishes a CRL (see RFC2459). CRL is a certificate serial number and is signed by CA. If the serial number of a certificate is listed in the CRL, that certificate is revoked and it is no longer valid. Most certificates have a extension called CRL Distribution Point (CDP). CDP is usually an HTTP or Lightweight Directory Access Protocol (LDAP) URL, which indicates where the CRL is stored. My VeriSign certificate is http://crl.verignign.com/class1.crl. This CRL has more than 500 K, so it takes some time to download.
Java indeed provides class java.security.cert.ldapcertStoreParameters, which can be used to get a CRL from a LDAP directory, but this does not apply to VeriSign CRL (because the CRL is on a web server, not an LDAP server) . Microsoft has a richer API than Java to manage certificates to undo. If you browse a secure website (HTTPS), IE will verify that the server has been revoked (assuming the server's certificate has a CDP). IE will get CRLs from the CAS in the certificate chain and cache them into the Temporary Internet Files of the IE. When the CRL from that CA is required next time, IE will first check the cache. If it finds the CRL in the cache, IE will check if the CRL has expired. (CRLS also has a valid from / to period .veriSign uses a 10-day payment period.) If the CRL has expired, IE will get a new CRL.
I consider developing a CRL access, cache, cache, caching confirmation only for Java - but you will need a lot of Java code, you need to support several URL protocols (HTTP, LDAP, FTP, files), need to be stored with a file CRL caching and requires copying the underlying framework provided by Microsoft. The purpose is to use IE's certificate to undo the bottom frame.
Microsoft provides a function CERTVOCIREVOCATION (), which combines the IE cache and downloads and processes the CRLS as needed. I wondered for several weeks to cancel the process, and finally got a reliable algorithm. When CertverifyRecocation () downloads a CRL, the download sometimes is interrupted. This makes CertverifyRevocation () return to fake, difficult to recover the wrong condition. The process I implemented is shown in Figure 1. Figure 1. Certificate revoked process table
It is to call the function CRYPTRETRIEVEOBJECTBYURL () to prefipe from the LDAP, HTTP, or FTP server, and then call CertverifyRevocation () to check if this certificate has been revoked. Although CryptretrieveObjectByurl () download is still subject to the influence of the network, the advantage of using CryptRetrieveObjectByURL () is that you can identify the problem, report a meaningful error message, and (if you need) you can prompt the user to accept or reject the certificate. Unfortunately, only WINDOWS 2000 or higher is CryptRetrieveObjectByURL (). If the program is to run on Windows 98 or Windows NT4, you cannot prefetch CRL.
I also try to use the Microsoft function to download CRLs and then process the CRL in Java. This way is slow in a large CRL (such as VeriSign CRL).
Listing 3 Displays the Java code snippet for the iScertrevoked () method. The iScertrevoked () method calls two local functions, MsgetCrl (), and MsverifycertRevocation (). MsgetCrl () calls Microsoft Functions CRYPTRETRIEVEOBJECTBYURL (). If CRL is not in the cache, it can be downloaded by CRL. You don't need to pass the CRL to Java because it never used in Java. The function mscertverifyrevocation () calls Microsoft Functions CERTVERIFYREVOCATOIN () to determine if a certificate is undo. Listing 4 Displays a code snippet for MsgetCrl () and Msverifycertrevocation (). Warning: When I first test CERTVERIREVOCATION () on the Windows 2000 Server PC, it did not run. After I upgraded the PC to Service Pack 2, I will be successful.
The ISCERTREVOKED () method in our confirmation program calls two local functions: MsgetCrl () and MsverifyCertRevocation () (shown in Listing 4). boolean isCertRevoked (X509Certificate cert, int DontKnowFlag) {byte [] certblob = cert.getEncoded (); // Does the cert have a CDP (// CRL distribution point) ??? byte [] CDPblob = cert.getExtensionValue ( "2.5 .29.31 "); // Yes there is a cdp - asn parse the cdpstring [] urlarray = msf.mstring [] Urlarray = msf.mstring [] URLARRAY = MSF.MspARSECDP (CDPBLOB); for (int i = 0; i Functions MsgetCrl () and MSVerifyCertRevocation () are called by method iscertrevoked () (as shown in list 3). MsgetCrl () calls Microsoft Functions CRYPTRETRIEVEOBJECTBYURL (), if there is no CRL in the cache, you can download it with this function. Functions MSVERIFYCERTREVOCATION () calls Microsoft Functions CERTVERIFYREVOCATION () to see if a certificate has been revoked. MSgetCRL (jstring jurl) {if {printf ( "CryptRetrieveObjectByUrl failed / n") (CryptRetrieveObjectByUrl (url, CONTEXT_OID_CRL, 0, timeout * 1000, (LPVOID) & crl, NULL, NULL, NULL, NULL)!); // cached url is corruptedDeleteUrlCacheEntry (url); return JNI_FALSE;} return JNI_TRUE;} MSVerifyCertRevocation (jbyteArray jCert) {rgpvContext [0] = (PVOID) pCertContext; if (CertVerifyRevocation (X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, rgpvContext, 0, NULL, & status)) { Return 1; // CERT IS Not Revoked} if (status.dwerror == crypt_e_revoked) Return 0; // CERT IS Revoked Return -2; // processing error} KeyManager javax.net.ssl.x509keyManager has six ways: • getClientaliaseses () Returns a group of clients. (An alias here is an identity with an RSA private key and certificate.) GetServeraliaSes () Returns a set of server alias. · ChooseClientalias () Select a client side name from a set of names. · ChooseServeralias () Select a server alias from a set of names. GetCertificateChain () returns an orderly certificate chain for a certificate. GetPrivateKey () returns a private key for an individual name. Microsoft stores private keys and their related certificates in the file system. My private key and certificate are stored in the directory C: / Documents and Settings / Administrator / Application Data / Microsoft. You don't need to know where the key is stored, because Microsoft provides an API to access the key and certificate library. KeyManager's getClientaliaSES () and GetServeraliases () methods perform Microsoft's local functions CertenumcestificatelnStore (), view all certificates in Microsoft's "My" certificate library. The certificate in the "MY" certificate library should have a private key associated with them. Each certificate / private key combination has a special identifier called Container; this is equivalent to "alias" in Java (see List 5). The CERTENUMCERTIFICATESINSTORE () method see all the certificates in the "My" certificate library in Microsoft; each certificate has a related private key. Each certificate / private key combination has an identifier called Container, which is equivalent to alias in Java. JobjectArray MSgetAliases (jstring jcertStore) {// open Microsoft certificate storehSystemStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, certStore); // read all the certificateswhile (pCertContext = CertEnumCertificatesInStore (hSystemStore, pCertContext)) {// get the cert key container nameCertGetCertificateContextProperty (pCertContext, CERT_KEY_PROV_INFO_PROP_ID, alias, & propLen); // add to list of aliasesAddDataToList (& list, alias, strlen (alias) 1);} return jaliases;} List 5 Method ChooseClientalias () and ChoOSeselVeralias () Return to a client (or server) alias from a list of albums. If there is only one alien, there will be no dismissal when selecting alias. Because Java's founders do not provide any special guidance for choosing any special guidance, I have chosen the first alias in the list. Another way to choose a suitable client side name is to prompt the user to select an alias from a list possible alias. (In the SSL client, you can usually do this, but you can't do it on the server.) KeyManager's getCertificatechain () method is a certificate returning an orderly certificate chain. This method gets a trusted certificate issuer by calling the getAcceptedissuers () method. First we find the Distinguished name (DN) of the certificate issuer, and then we look at which trusted issuer has that DN. Several issuers can have the same DN. For each certificate with the issuer DN, we extract the public key and try to confirm the signature on the original certificate. If there is no signator with the correct DN and the correct public key, the certificate chain is destroyed, an exception occurs. If we find the certificate issued by the correct issuer, we repeat the above process to find and confirm the issuer of that certificate. Repeat the process until we reach root CA. For an root CA, Subject DN, and the issuer DN are the same (see List 6). Method getCertchain () returns an orderly certificate chain for a certificate. MSCryptoFunctions MSF = new MSCryptoFunctions (); X509Certificate [] getCertChain (X509Certificate cert) {try {getCACerts (); Principal subject = cert.getSubjectDN (); Principal issuer = cert.getIssuerDN (); CertChainList.add (cert); // stop if issuer == subject (root CA) while {match = false ((issuer.equals (subject))!); X509CertSelector xcs = new X509CertSelector (); xcs.setCertificateValid (new Date ()); Collection certcollection = cACerts. Getcertificates (XCS); //// The next 7 lines are inserted to work // around a problem with x509certselector.// We Should Be Able to do this with // xcs.setsubject (issuer.tostring ()); // Iterator iter = certcollection.iterator (); while (ore.hasnext ()) {x509certificate cace = (x509certificate) (iter.next ()); if (! Cacer.getsubjectdn (). Equals (Issuer) iter.remove );} issuerArray = new X509Certificate [certcollection.size ()]; issuerArray = (X509Certificate []) certcollection.toArray (issuerArray); for (int i = 0; i <> issuerArray.length; i ) if (verifySignature (Issuerarray [i], CE RT)) {match = true; certificate = IssueraRray [i]; Subject = ceert.getsubjectdn () Issuer = ceert.getissuerdn (); CertchainList.Add (CERT); Break;} if (! Match) {return null; // CERT chain broom}}} catch (Exception E) {E.PrintStackTrace ();} x509certificate [] CERTCHAIN = New x509certificate [CertchainList.size ()]; CertchainList.Toarray (Certchain); returnickey;} getPrivateKey () method returns a private key to a separate name, assuming private keys can be output from the Microsoft key library. Remember, sometimes the private key cannot be output. (For example, if you use a encrypted smart card, no one can read private keys from the smart card.) If the private key cannot be output, getPrivateKey () returns a virtual private key. So, if getprivateKey () can't get the private key, we will cheat Java, let it think that it has been private. getPrivateKey () also caches aliases, so when a Java program tries to perform an RSA digital signature function, we will know which private key (cache alias), and Microsoft encryption provider can perform the RSA we want. Signature or decryption function (see List 7). Method getPrivateKey () returns a private key for an individual name, assuming private keys can be output from the Windows key library. MSCryptoFunctions MSF = new MSCryptoFunctions (); public PrivateKey getPrivateKey (String alias) {// get the private key from MS Windows for // this aliasbyte [] keyblob = MSF.MSgetPrivateKey (alias); if (keyblob == null) {/ / generate a dummy keyByte [] modblob = new byte [128]; for (i = 0; i <128; i ) modblob [i] = 127; mod = new biginteger (modblob); Exp = mod;} else {/ / use the key thing got exportedfor (i = 0; i Modblob [i] = keyblob [19-i (keysize / 16) * 2]; Expblob [i] = keyblob [19-i (keySize / 16) * 9]; MOD = New Biginteger (1, Modblob); Exp = New Biginteger (1, Expblob); } RsaprivateKeyspec privkeyspec = New RsapriVateKeyspec (MOD, EXP); KeyFactory Kf = KeyFactory.GetInstance ("RSA"); Privkey = kf.generateprivate (privkeyspec); Return privkey; } RSA Signature Provider java.security.signatureSPI class has five methods: · Engineinitsign () is the signature initial RSA signature engine. Engineinitverify () To confirm a signature initialization RSA signature engine. · EngineUpdate () adds data to signature or confirmation. · Enginesign () completes the signature operation and returns a digital signature. · Engineverify () Completes the signature - confirmation process, if the signature is correct, return true. Remember, digital signatures require private keys, confirm that a digital signature requires public key. If we have the right to use Microsoft's private key - that is, the private key is output - no need to perform the RSA signature operation in the Microsoft local code. But in some cases (for example, if we use a encrypted smart card), we have no need to use the private key. If the private key cannot be output, we must use the Microsoft local code to digitally sign. If the Java program uses the KeyManager method getPrivateKey () to get the private key, the alias of the private key is cached. When the RSA Signature Provider is signed, we reuse the cache alias, and call the Microsoft local function to perform the signature operation without exposing the private key. (This sounds some false, but it is really feasible.) Note that there is no private key in Engineinitsign (). I use the Java JCE hash function and then generate RSA signatures from the hash file with Microsoft Cryptographic Province from the hash file. Improve the Java Signature class by adding an EngineInitSign method: MSCryptoFunctions MSF = new MSCryptoFunctions (); protected void engineInitSign (PrivateKey privateKey) {MSF.MSrsaSignInit ((byte []) null, "MD5");} protected byte [] engineSign () {byte [] hash = MD5.digest ( ); Byte [] mssig = msf.msrsignhash (haveh, (byte []) NULL, "MD5"); Return Mssig;} We can implement signatures in Microsoft local code - confirm, but there is no advantage. In the implementation, we use the JSSE provider to perform confirmation in Java: protected void engineInitVerify (PublicKey publicKey) {jsse = Signature.getInstance ( "MD5withRSA", "SunJSSE"); jsse.initVerify (publicKey);} protected boolean engineVerify (byte [] sigBytes) {boolean verifyresult = false; verifyresult = jsse. Verify (Sigbytes); RSA Cipher Provider Javax.crypto.cipherspi class has 12 methods: • Engineinit () Cipher Provider. · EngineUpdate () Continue to an encryption or decryption operation consisting of multiple parts. · EnginedOfinal () encrypts or decrypts data in a single operation, or completes an operation consisting of multiple parts. ENGINEGETBLOCKSIZE () Returns the zone size (in byte form). ENGINEGETIV () Returns the initial test vector. It is not used for RSA passwords. ENGINEGETKEYSIZE () Returns the key size of a specific key object. · EnginegetOutputSize () returns the output length in byte, and the output buffer requires this length to save the result of the next Update or DOFINAL operation, the input length is assumed. ENGINEGETPARETERS () Returns the parameters used by this password. · EnginesetMode () Set the password mode (encryption or decryption). · EngineSetPadding () Sets the fill mechanism for this password (currently only PKCS1 fill). · EngineWrap () Package a key (not implemented). · Engineunwrap () Unnovation a key (not implemented). The RSA encryption process requires a public key; RSA decryption requires private key. If we have the right to use the RSA private key in the Microsoft keyhouse - that is, the private key is to output - then there is no need to perform RSA password operations in the Microsoft local code. But in some cases (for example, if we use a encrypted smart card), we do not have to use the private key. If the private key cannot be output, we must decrypt the RSA with the Microsoft local code. The implementation of the RSA password in the Windows local code is simple. The essential decryption process is as follows: MSrsaDecrypt (jstring jpadalg, jbyteArray jdata) {CryptAcquireContext (& hDecryptProv, alias, NULL, PROV_RSA_FULL, 0); CryptGetUserKey (hDecryptProv, AT_KEYEXCHANGE, & hDecryptKey); CryptDecrypt (hDecryptKey, 0, TRUE, 0, encryptblob, & ndata); return decryptblob;} Encryption is almost the same. Because the RSA encryption only needs public key, the encryption mode can be executed in Java. I chose to implement RSA encryption and decryption in the Windows local code because it is easy. The RSA password is an encryption algorithm for US government control. If you want to combine RSA Cipher Provider with Sun JCE, you must create a JAR file, sign it with a DSA key, then add a certificate issued by Sun Microsystems. For convenience, I have put all the Mscrypto-Class files in a single package (com.boyter.mscrypto). In the signed JAR file, you only need MSRSacipherProvider.class and MSRSacipherFactoryImpl.class. JAR file used to create the signature and the Windows command: jar cvf mscrypto.jar comjarsigner -keystore keystore -storepass foobar mscrypto.jar jcesigner you can from "How to Implement a Provider for the Java Cryptography Extension 1.2.1." (See Resources A fifth step finds a description of the certificate for obtaining a JCE code from Sun. If you want to avoid the limitations of JCE (such as the US government's output control), you can replace JCE with a Clean-Room-style implementation environment (such as Beejce) instead of JCE. I have a program called MSRSATEST.JAVA that can be used to test Microsoft encrypted RSA signatures and RSA password providers. To do this, you must install an RSA private key and certificate in Microsoft Windows. There is a lot of good reasons for the use of Java security features with local Microsoft Windows security platforms, including reduced management fees, CRL confirmation and compatibility with smart cards. Another reason to combine Java JCE with Windows certificates and key bars is to manage Java tools for the Java certificate and key library. The Microsoft platform has a better graphical user interface (GUI) to manage Windows keys and certificate libraries. You can start the GUI by running the Certmgr.ext program (with Windows Platform SDK), or you can start from the IE window: Use the drop-down menu Tools | Internet Option, select the Content key, then select Certificate. When using KeyManager and TrustManager supported by Microsoft Encryption For JSS, you won't have any questions. Microsoft encrypted RSA Signature Provider and RSA Cipher Provider supported by Microsoft can also run, but cannot be used for JSSE.