"Turn" Java Deep Adventures (ix)--java security

Source: Internet
Author: User
Tags gettext asymmetric encryption

Original address: Http://www.infoq.com/cn/articles/cf-java-security

Security is an important part of the non-functional requirements of Java applications, and as with other non-functional requirements, security is easily overlooked by developers. Of course, for Java EE developers, the topic of security may be less familiar, and user authentication and authorization may be a feature of most Web applications. Frameworks like Spring Security also make development easier. This article does not discuss the security of Web applications, but rather introduces some of the underlying and basic aspects of Java security.

Certification

User authentication is an important part of application security and is designed to ensure that users of the application have legal identities. The term principal (Subject) is used in Java security to represent the source of the access request. A subject can be any entity. A principal can have multiple different identity identifiers (Principal). such as an application of the user such a subject, you can have a user name, ID card number and mobile phone number, such as a variety of identification. In addition to the identity, a principal can have public or private security-related credentials (credential), including passwords and keys.

The

Typical user authentication process is done through a login operation. Once the login is successful, a corresponding identity is available in a subject. Java provides an extensible login framework that allows application developers to easily customize and extend login-related logic. The logon process is initiated by logincontext . You need to specify the name of a login configuration (configuration ) when creating LoginContext. This login configuration contains information for multiple loginmodule required for login. Each Loginmodule implements a login method. When calling LoginContext's login method, each loginmodule configured will be invoked to perform the login operation. If the entire logon process succeeds, the getsubject method allows you to obtain the principal that contains the identity information. Developers can implement their own loginmodule to customize different login logic.

The login method for each loginmodule consists of two stages. The first phase is in the implementation of the login method. This phase is used to perform the necessary authentication, which may require access to the user's input, as well as a database, network operation, or other means to complete the certification. When the certification is successful, save the necessary information. If the authentication fails, the associated exception is thrown. The second stage is in the commit or abort method. Because a login process may involve multiple loginmodule. LoginContext will determine the success of this login based on the authentication results of each loginmodule and the relevant configuration information. LoginContext is used to judge the necessity of each loginmodule for the entire login process, which is divided into the necessary, necessary, sufficient and optional four cases. If the login succeeds, the Commit method for each loginmodule is called to associate the identity with the principal. If the login fails, the Loginmodule abort method is called to clear the previously saved authentication-related information.

In the process of loginmodule authentication, if you need to get the input of the user, it can be done by CallbackHandler and corresponding callback. Each Callback can be used to perform the necessary data transfer. The typical startup logon process is as follows:

Public Subject Login () throws loginexception {        Textinputcallbackhandler callbackhandler = new Textinputcallbackhandler ();        LoginContext LC = new LoginContext ("Smsapp", CallbackHandler);        Lc.login ();        

The Smsapp here is the name of the login configuration, which can be found in the configuration file. The contents of this configuration file are also simple.

Smsapp {        

The login module using Security.login.SmsLoginModule is declared here, and the module is required. The configuration file can be specified by the parameter java.security.auth.login.config when the program is started, or modify the JVM's default settings. Here's a look at the core methods of Smsloginmodule login and commit.

 public Boolean login () throws Loginexception {Textinputcallback phoneinputcallback = new Textinputcallback ("P        Hone number: ");        Textinputcallback smsinputcallback = new Textinputcallback ("Code:");        try {handler.handle (new callback[] {phoneinputcallback, smsinputcallback});        } catch (Exception e) {throw new Loginexception (E.getmessage ());        } String Code = Smsinputcallback.gettext (); Boolean isValid = Code.length () > 3;       This is just a simple validation.        if (isValid) {PhoneNumber = Phoneinputcallback.gettext (); } return isValid;} public Boolean commit () throws Loginexception {if (PhoneNumber! = null) {subject.getprincipals (). Add (n           EW Phoneprincipal (PhoneNumber));    return true; } return false;}    

Here, two textinputcallback are used to get the user's input. When the user input code is valid, the relevant information is recorded, here is the user's mobile phone number. In the Commit method, the mobile number is associated with the subject as the user's identity.

Permission control

After verifying the legal identity of the access request source, another task is to verify that it has the appropriate permissions. Permissions are represented by Permission and its subclasses. Each permission has a name, and the meaning of the name is related to the permission type. Some permissions have a list of actions corresponding to them. Typically, the file Operation permission filepermission, whose name is the path to the file, and its list of actions include read, write, execute, and so on. The most important thing in the permission class is the implies method, which defines the containment relationship between permissions and is the basis for validation.

Permissions control includes two sections for management and validation. Management refers to defining a permission control policy in an application, while validation refers to determining whether a request is legitimate at run time based on a policy. A policy can be associated with a principal, or it can have no association. Policies are represented by policy, and the JDK provides a basic implementation based on file storage. Developers can also provide their own implementations. There may only be one policy in effect while the app is running. The specific performer of the validation section is Accesscontroller, where the checkpermission method is used to verify that the given permission is allowed. You need to call the Checkpermission method to authenticate before executing the associated access request in your app. If the validation fails, the method throws a accesscontrolexception exception. Access control checks are provided in the JVM for access to critical portions of the content, but only when the application is started with the security Manager enabled by the parameter-djava.security.manager, and is aligned with the policy.

Another concept associated with access control is privileged actions. A privileged action is concerned only with the permissions required by the action itself, and does not care who the caller is. For example, a privileged action to write to a file, which only requires write access to the file, does not concern who is asking it to perform such an action. The privileged action is divided into privilegedaction and privilegedexceptionaction, depending on whether the exception is thrown. Both interfaces have only one run method to perform the related actions, or they can return the result to the caller. A privileged action can be performed by Accesscontroller's Doprivileged method.

Java security uses the concept of a protected domain. Each protection domain contains a set of classes, identities, and permissions, meaning that instances of these classes automatically have the given permissions when the source of the access request is the identity. The rights to protect a domain can be either fixed or dynamically changed according to the policy. The Protectiondomain class is used to represent a protected domain, and its two construction methods are used to support static and dynamic permissions, respectively. In general, applications typically involve system protection domains and application protection domains. Many method invocations may span the boundaries of multiple protection domains. Therefore, when Accesscontroller for access control validation, the invocation context of the current operation needs to be considered, mainly referring to the different protection domains belonging to different methods on the method call stack. This invocation context is typically tied to the current thread. The Accesscontroller getcontext method allows you to obtain a AccessControlContext object that represents the calling context, which is equivalent to a snapshot of the call stack required for access control validation. In some cases, this object will need to be passed to facilitate access control validation in other threads.

Consider the following permission validation code:

Subject Subject = new Subject (); Viewerprincipal principal = new Viewerprincipal ("Alex"); Subject.getprincipals (). Add (Principal); Subject.doasprivileged (Subject, New privilegedaction<object> () {public        Object run () {               new Viewer (). View ();                return null;       

Here, a new Subject object is created and associated with the identity. Typically, this process is done by a login operation. A privileged action can be performed by subject's Doasprivileged method. The view method of the viewer object uses Accesscontroller to check whether the permissions are appropriate. The content of the policy configuration file is also relatively simple, and the file path can be specified by parameter Java.security.auth.policy when starting the program.

Grant Principal Security.access.ViewerPrincipal "Alex" {    
Encryption, decryption, and signing

Building Secure Java applications requires encryption and decryption. The Java Cryptography Framework employs a common service provider architecture to provide the scalability and interoperability required. The password framework provides a range of commonly used services, including encryption, digital signatures, and newspaper Digest. These services have a service provider interface (SPI), and the service's implementation only needs to implement these interfaces and register them in the password framework. For example, the cryptographic service Cipher The SPI interface is CIPHERSPI. Each service can have a different algorithm to implement. The password framework also provides the appropriate factory method to obtain an instance of the service. For example, to use the MD5 algorithm to serve the digest, only need to call Messagedigest.getinstance ("MD5") can be.

The key is essential in the encryption and decryption process. Cryptographic algorithms are generally divided into symmetric and asymmetric two types. The symmetric encryption algorithm uses the same key for encryption and decryption, while the asymmetric encryption algorithm uses a pair of public and private keys, and the other one is used for decryption when one is encrypted. Different encryption algorithms, there are different keys. Symmetric encryption algorithms use Secretkey, while asymmetric encryption algorithms use PublicKey and privatekey. Another interface that corresponds to key keys is KeySpec, which is used to describe the specific contents of the keys for different algorithms. For example, a typical way to use symmetric encryption is as follows:

Keygenerator generator = keygenerator.getinstance ("DES"); Secretkey key = Generator.generatekey (); SaveFile ("Key.data", key.getencoded ()); Cipher Cipher = cipher.getinstance ("DES"); Cipher.init (Cipher.encrypt_mode, key); String text = "Hello world"; byte[] encrypted = Cipher.dofinal (Text.getbytes ()); SaveFile ("Encrypted.bin", encrypted);

Encryption is the first to generate a key, and then by the cipher service to complete. The contents of the key can be saved for easy delivery to the program that needs to be decrypted.

byte[] KeyData = GetData ("Key.data"); Secretkeyspec KeySpec = new Secretkeyspec (KeyData, "DES"); Cipher Cipher = cipher.getinstance ("DES"); Cipher.init (Cipher.decrypt_mode, KeySpec); byte[] data = GetData (" Encrypted.bin "); byte[] result = cipher.dofinal (data);

When decrypting, the content of the key code is obtained from the saved file, then the content of the key itself is obtained through Secretkeyspec and then decrypted.

The purpose of the Newspaper Digest is to prevent the information from being intentionally or unintentionally modified. By applying some algorithms to the original data, a checksum can be obtained. When the data is received, only the same algorithm should be applied, and then compare the parity of the checksum, you can determine whether the data has been modified. Compared to the original data, the check code length is smaller and easier to compare. Messageauthenticationcode is similar to the quote digest, except that the key is added to the calculation process, and only the recipient who has mastered the key can verify the integrity of the data.

The function of digital signature can be realized by using public key and private key. A sender uses the private key to encrypt a message, and the recipient uses the public key to decrypt it. Since the private key is only known to the sender, when the recipient uses the public key decryption succeeds, it can be determined that the source of the message is definitely a specific sender. This is equivalent to the sender signing the message. Digital signatures are provided by the Signature service, and the process of signing and validating is straightforward.

Signature Signature = signature.getinstance ("Sha1withdsa"); Keypairgenerator keygenerator = keypairgenerator.getinstance ("DSA"); KeyPair KeyPair = Keygenerator.generatekeypair (); Privatekey Privatekey = Keypair.getprivate (); signature.initsign (Privatekey); byte[] data = "Hello World". GetBytes (); Signature.update (data); byte[] SignatureData = Signature.sign (); Get signed PublicKey PublicKey = Keypair.getpublic (); signature.initverify (PublicKey); signature.update (data); Boolean result = Signature.verify (signaturedata); To verify

Verify that the public key used by the digital signature can be published by means of a file or certificate.

Secure Sockets Connection

In all kinds of data transmission methods, network transmission is now widely used, but there are more security risks. A Secure socket connection refers to encrypting a socket connection. The symmetric encryption algorithm can be selected when encrypting. But how to secure the shared secret between sender and receiver is a very troublesome problem. If the encryption key is used again, it becomes a circular problem. The asymmetric encryption algorithm is suitable for this case. The private key is kept in its own, and the public key. When the data is sent, it is encrypted with the private key, the receiver is decrypted with the public public key, and when the data is received, the opposite is true. This approach solves the problem of shared keys, but another issue is how to ensure that the public key received by the receiver really comes from the sender being declared, not forged. For this reason, the concept of certificates is introduced. The certificate contains the identity and the corresponding public key. The certificate is issued by a user-trusted authority and is encrypted with the private key of the institution. In some cases, the authenticity of a certificate authority will need to be certified by another agency's certificate. Through this proof relationship, a certificate chain is formed. And the root of the chain is recognized as a trustworthy institution. The public key given in the certificate can be trusted only when all certificates on the certificate chain are trusted.

In the daily development of the more frequent contact is HTTPS, that is, a secure HTTP connection. Most of the errors that occur when using a Java program to access HTTPS sites are related to the certificate chain. Some websites use a certificate that is not issued by a formal security authority, or the certificate has expired. If you must have access to such an HTTPS Web site, you can provide your own socket factory and host name validation classes to circumvent the past. Another approach is to import the certificate into the system's trust certificate library through the keytool tool.

URL url = new URL ("https://localhost:8443"); Sslcontext context = sslcontext.getinstance ("TLS"), Context.init (new keymanager[] {}, new trustmanager[] {new Mytrustmanager ()}, New SecureRandom ()); Httpsurlconnection connection = (httpsurlconnection) url.openconnection (); Connection.setsslsocketfactory ( Context.getsocketfactory ()); Connection.sethostnameverifier (new Myhostnameverifier ());

The Mytrustmanager here implements the X509trustmanager interface, but all methods are the default implementations. The Myhostnameverifier implements the Hostnameverifier interface, where the Verify method always returns True.

Resources
    • Java Security Architecture
    • Java cipher Framework (JCA) Reference Guide
    • Java Certification and Licensing Services (JAAS) Reference Guide
    • Java Secure Sockets Extension (JSSE) Reference Guide

"Turn" Java Deep Adventures (ix)--java security

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.