The RSA public-private key generated by Java OpenSSL for data encryption and decryption is introduced in detail

The RSA public-private key generated by OpenSSL is used for data encryption and decryption in Java

What is RSA: RSA public key encryption algorithm was developed by Ron Rivest ADI Shamir and Len Adleman (Massachusetts Institute of technology, USA). RSA is named after the three of them. RSA is the most influential public key encryption algorithm at present. It can resist all known cryptographic attacks and has been recommended by ISO as the public key data encryption standard. At present, this encryption method is widely used in online banking, digital signature and other occasions. RSA algorithm is based on a very simple algorithm The fact of number theory: it is very easy to multiply two large prime numbers, but it was extremely difficult to factorize the product at that time, so the product can be disclosed as an encryption key.

What OpenSSL is: many cryptographic algorithms, public key infrastructure standards and SSL protocol. Perhaps these interesting functions will give you the idea of implementing all these algorithms and standards. If so, while expressing admiration for you, I can't help reminding you that this is a daunting process. This work is no longer as simple as reading several cryptography monographs and protocol documents, but to understand every detail of all these algorithms, standards and protocol documents, and implement these definitions and processes one by one with C language characters you may be familiar with. We don't know how long it will take you to finish this interesting and terrible work, but it's certainly not a matter of one or two years. OpenSSL is a collection of many security algorithms written by Eric A. young and Tim J. Hudson since 1995. Through commands or development libraries, we can easily implement standard public algorithm applications.

My hypothetical application background:

With the popularity of mobile Internet, applications developed for mobile devices are emerging one after another. These applications are often accompanied by user registration and password authentication. " There are hidden dangers in the security of "network transmission" and "application log access". Password, as a user's sensitive data, especially requires developers to take security precautions before the application goes online. Improper handling may cause problems such as malicious attacks by commercial competitors and litigation by third-party partners.

Although RSA algorithm has so many advantages, we can't find a complete example on the Internet to illustrate how to operate. Let me introduce:

1、 Use OpenSSL to generate private and public keys

I use the Linux system and have installed the OpenSSL package. At this time, please verify that OpenSSL is installed on your machine. The following information should appear when running the command:

First, generate the private key:

This command causes OpenSSL to randomly generate a private key with an encryption length of 1024 bits. Encryption length refers to the maximum allowable length of "encrypted information" in theory, that is, the length limit of plaintext. With the increase of this parameter (for example, 2048), the allowable plaintext length will also increase, but at the same time, it will also cause a rapid increase in computational complexity. The recommended length is 1024 bits (128 bytes).

Let's take a look at the contents of the private key:

The contents are standard ASCII characters, with obvious marks at the beginning and end of the line. The real private key data is an irregular character in the middle.

Supplement on March 24, 2015: the key file finally stores the data through Base64 coding. You can see that the length of each line of the above key file is very regular. This is because rfc2045 stipulates that the encoded output stream must be represented in lines of no more than 76 characters each. In other words, the data encoded by Base64 shall not exceed 76 characters per line at most. For ultra long data, it needs to be divided by line.

Next, generate the public key according to the private key:

Let's look at the contents of the public key:

At this time, the private key cannot be used directly, and pkcs#8 coding is required:

The command indicates that the input private key file is RSA_ private_ key. PEM, the output private key file is pkcs8_ rsa_ private_ key. PEM, without any secondary encryption (- nocrypt)

Let's see if the encoded private key file is different from the previous private key file:

At this point, the available key pairs have been generated, and the private key uses pkcs8_ rsa_ private_ key. PEM, public key RSA_ public_ key. pem。

Supplement on May 20, 2014: Recently, RSA encryption is required again, and the other party requires that only the private key file generated in the first step without pkcs#8 coding can be used. Later, I checked the relevant literature and learned that the private key file code generated in the first step is in pkcs#1 format, which is actually supported by Java, but only two lines of code are written:

First read out the pkcs#1's private key file (note that the comments at the beginning of the minus sign are removed), and then use Base64 to decode the read string to get prikeydata, which is the parameter in the first line of code. The last line gets the private key. The following usage is no different. References: https://community.Oracle.com/thread/1529240?start=0&tstart=0

2、 Writing java code and actual testing

Supplement on February 23, 2012: the standard JDK only stipulates that JCE (Java cryptography extension) is a group of packages, which provide the framework and Implementation for encryption, key generation and negotiation, and message authentication code (MAC) algorithm. It provides encryption support for symmetric, asymmetric, block and stream ciphers. It also supports secure streams and sealed objects.) Interface, but the internal implementation needs to be provided by itself or a third party. Therefore, we use bouncycastle's open source JCE implementation package here. Download address: http://bouncycastle.org/latest_releases.html , I use bcprov-jdk16-146 Jar, this is in jdk1 6 used in the environment. If you need an implementation under another JDK version, you can find the corresponding version in the previous download page.

Let's take a look at the code I implemented:

In the code, I provide two ways to load the public key and private key. Read by stream: it is suitable for Android applications to index resources by ID to get InputStream; Read by string: as shown in the code, store the key content in the static constant by line, and import the key by string type.

Run the above code and the following information will be displayed:

In the main function, I commented out "rsaencrypt Genkeypair() ", this method is used to randomly generate key pairs (only generate and use, not store). When the file key is not used, you can annotate the code loaded with the key, enable this method, or run through the code. The difference between loading the public key and loading the private key is that x509encoded keyspec is used when loading the public key (x509 encoded key instruction). Pkcs8encoded keyspec (pkcs#8 encoded key instruction) is used when loading the private key.

Added on February 22, 2012: in the process of Android Software development, it was found that the above code could not work normally, mainly due to sun misc. Base64decoder class does not exist in Android development kit. Therefore, you need to find the source code of rt.jar on the Internet, especially src.jar of JDK Zip. This is only part of the source code in the JDK. There is no code for the above classes. After searching and adding, the above code can work well in Android applications. It contains the corresponding code of this class. In addition, this class relies on the ceformatexception, cestreamexhausted, characterdecoder and characterencoder classes and exception definitions.

Added on February 23, 2012: at first, I wrote this article to realize RSA encryption and decryption without relying on any third-party package. However, I encountered problems later. Since a cipher object needs to be established in both the encryption method encrypt and the decryption method decrypt, this object can only obtain instances through getInstance. It has two types: the first is to specify only the algorithm without specifying the provider; The second is to specify both. If it is not specified at first, the code can still run through, but you will find that the result of each encryption is different. Later, the analysis found that the public and private keys used by the cipher object were randomly generated internally, not the public and private keys specified in the code. Strangely, this code that does not specify a provider can run through Android applications, and the result of each encryption is the same. I think, in addition to some development functions of the system, Android SDK also implements the function of JDK. Maybe it has provided corresponding providers in its own JDK, so that the encryption results are the same every time. When I added bouncycastle's provider like the example code on the Internet, the result of each encryption was the same.

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>