Java Cryptography 简明教程
Java Cryptography - Introduction
密码学是制造能够提供信息安全的密码系统的艺术和科学。
密码学处理数字数据的实际安全保护。它指的是基于数学算法设计的机制,这些机制提供基本的信息安全服务。您可以将密码学视作一个包含安全应用程序中不同技术的大型工具包。
What is Cryptanalysis?
破解密文文本的艺术和科学被称为密码分析。
密码分析是密码学的一个相关分支,两者共存。密码过程生成密文文本用于传输或存储。它涉及学习密码机制以破解它们。密码分析还用于设计新密码技术来测试其安全强度。
Java Cryptography - Message Digest
哈希函数非常有用,并且出现在几乎所有信息安全应用程序中。
哈希函数是一种数学函数,它将数字输入值转换成另一个压缩数字值。哈希函数的输入长度是任意的,但输出总是固定长度。
哈希函数返回的值称为 message digest 或简单称为 hash values 。下图为哈希函数的插图。
Java 提供了一个名为 MessageDigest 的类,它属于 java.security 包。此类支持算法,例如 SHA-1、SHA 256、MD5 算法,以将任意长度的消息转换为消息摘要。
要将给定的消息转换为消息摘要,请按照以下步骤操作 −
Step 1: Create a MessageDigest object
MessageDigest 类提供名为 getInstance() 的方法。此方法接受一个 String 变量,指定要使用的算法名称,并返回实现指定算法的 MessageDigest 对象。
如下所示,使用 getInstance() 方法创建 MessageDigest 对象。
MessageDigest md = MessageDigest.getInstance("SHA-256");
Step 2: Pass data to the created MessageDigest object
在创建消息摘要对象之后,你需要将消息/数据传递给它。你可以使用 MessageDigest 类的 update() 方法来做到这一点,此方法接受表示消息的字节数组,并将其添加到/传递到上面创建的 MessageDigest 对象中。
md.update(msg.getBytes());
Step 3: Generate the message digest
你可以使用 digest() 方法生成消息摘要。MessageDigest 类的方法会在当前对象上计算哈希函数,并以字节数组的形式返回消息摘要。
使用 digest 方法生成消息摘要。
byte[] digest = md.digest();
Example
以下是一个示例,它从文件中读取数据并生成消息摘要并将其打印出来。
import java.security.MessageDigest;
import java.util.Scanner;
public class MessageDigestExample {
public static void main(String args[]) throws Exception{
//Reading data from user
Scanner sc = new Scanner(System.in);
System.out.println("Enter the message");
String message = sc.nextLine();
//Creating the MessageDigest object
MessageDigest md = MessageDigest.getInstance("SHA-256");
//Passing data to the created MessageDigest Object
md.update(message.getBytes());
//Compute the message digest
byte[] digest = md.digest();
System.out.println(digest);
//Converting the byte array in to HexString format
StringBuffer hexString = new StringBuffer();
for (int i = 0;i<digest.length;i++) {
hexString.append(Integer.toHexString(0xFF & digest[i]));
}
System.out.println("Hex format : " + hexString.toString());
}
}
Java Cryptography - Creating a MAC
MAC(消息认证码)算法是对称密钥加密技术,用来提供消息认证。为了建立 MAC 流程,发送者和接收者共享对称密钥 K。
本质上,MAC 是在底层消息上生成的一种加密校验和,它与消息一起发送,以确保消息认证。
使用 MAC 进行认证的过程如下图所示 −
在 Java 中, javax.crypto 软件包的 Mac 类提供了消息认证代码的功能。按照如下给出的步骤,可以使用此类创建消息认证代码。
Step 1: Create a KeyGenerator object
KeyGenerator 类提供 getInstance() 方法,它接受一个代表所需的密钥生成算法的 String 变量,并返回一个生成密钥的 KeyGenerator 对象。
使用所示方法 getInstance() 创建 KeyGenerator 对象,如下所示。
//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
Step 2: Create SecureRandom object
java.Security 包的 SecureRandom 类提供了一个强随机数发生器,用于在 Java 中生成随机数。Instantiate 此类,如下所示。
//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();
Step 3: Initialize the KeyGenerator
KeyGenerator 类提供一个名为 init() 的方法,此方法接受 SecureRandom 对象并初始化当前 KeyGenerator 。
使用此方法初始化在上一步中创建的 KeyGenerator 对象。
//Initializing the KeyGenerator
keyGen.init(secRandom);
Step 4: Generate key
使用 KeyGenerator 类的 generateKey() 方法生成密钥,如下所示。
//Creating/Generating a key
Key key = keyGen.generateKey();
Step 5: Initialize the Mac object
Mac 类的 init() 方法接受 Key 对象,并使用给定的密钥初始化当前 Mac 对象。
//Initializing the Mac object
mac.init(key);
Step 6: Finish the mac operation
Mac 类的 doFinal() 方法用于完成 Mac 操作。以下所示,将以字节数组形式传递所需数据到此方法,并完成操作。
//Computing the Mac
String msg = new String("Hi how are you");
byte[] bytes = msg.getBytes();
byte[] macResult = mac.doFinal(bytes);
Example
以下示例演示如何使用 JCA 生成 Message Authentication Code (MAC)。此处,我们使用简单的消息“Hi how are you”,并为该消息生成 Mac。
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
public class MacSample {
public static void main(String args[]) throws Exception{
//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();
//Initializing the KeyGenerator
keyGen.init(secRandom);
//Creating/Generating a key
Key key = keyGen.generateKey();
//Creating a Mac object
Mac mac = Mac.getInstance("HmacSHA256");
//Initializing the Mac object
mac.init(key);
//Computing the Mac
String msg = new String("Hi how are you");
byte[] bytes = msg.getBytes();
byte[] macResult = mac.doFinal(bytes);
System.out.println("Mac result:");
System.out.println(new String(macResult));
}
}
Java Cryptography - Keys
密码体制是密码技术及其伴随基础设施的实现,用来提供信息安全服务。密码体制也被称为 cipher system 。
基本密码体制的各种部件包括 Plaintext, Encryption Algorithm, Ciphertext, Decryption Algorithm, 加密密钥和解密密钥。
其中,
-
Encryption Key 是发送者知道的值。发送者将加密密钥与明文一起输入到加密算法中,以计算密文。
-
Decryption Key 是接收者知道的值。解密密钥与加密密钥相关,但并不总是相同的值。接收者将解密密钥与密文一起输入到解密算法中,以计算密文。
从本质上讲,基于加密/解密算法的类型,有两种类型的密钥/密码体制。
Java Cryptography - Storing keys
使用的/生成的密钥和证书存储在名为密钥库的数据库中。默认情况下,此数据库存储在名为 .keystore 的文件中。
您可以使用 java.security 包的 KeyStore 类访问此数据库的内容。这管理三个不同的条目,即 PrivateKeyEntry、SecretKeyEntry、TrustedCertificateEntry。
-
PrivateKeyEntry
-
SecretKeyEntry
-
TrustedCertificateEntry
Storing a Key in keystore
在本节中,我们将学习如何在密钥库中存储密钥。要将密钥存储在密钥库中,请按照以下步骤操作。
Step 1: Create a KeyStore object
java.security 包中的 KeyStore 类的 getInstance() 方法接收一个表示密钥库类型的字符串值,并返回一个 KeyStore 对象。
使用 getInstance() 方法创建 KeyStore 类的对象,如下所示。
//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");
Step 2: Load the KeyStore object
KeyStore 类的 load() 方法接受一个表示密钥库文件的 FileInputStream 对象以及一个指定 KeyStore 密码的 String 参数。
通常,密钥库存储在名为 cacerts 的文件中,位于 C:/Program Files/Java/jre1.8.0_101/lib/security/ 位置,其默认密码为 changeit ,可以使用 load() 方法加载,如下所示。
//Loading the KeyStore object
char[] password = "changeit".toCharArray();
String path = "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts";
java.io.FileInputStream fis = new FileInputStream(path);
keyStore.load(fis, password);
Step 3: Create the KeyStore.ProtectionParameter object
按如下所示实例化 KeyStore.ProtectionParameter。
//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);
Step 4: Create a SecretKey object
通过实例化其子类 SecretKeySpec 来创建 SecretKey (接口)对象。在实例化时,您需要将密码和算法作为参数传递给它的构造函数,如下所示。
//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec(new String(keyPassword).getBytes(), "DSA");
Step 5: Create a SecretKeyEntry object
通过传递在上述步骤中创建的 SecretKey 对象来创建 SecretKeyEntry 类的对象,如下所示。
//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);
Step 6: Set an entry to the KeyStore
KeyStore 类的 setEntry() 方法接收一个表示密钥库条目别名的字符串参数、一个 SecretKeyEntry 对象和一个 ProtectionParameter 对象,并将条目存储在给定的别名下。
使用 setEntry() 方法将条目设置到密钥库,如下所示。
//Set the entry to the keystore
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);
Example
以下示例将密钥存储在“cacerts”文件中(Windows 10 操作系统)。
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class StoringIntoKeyStore{
public static void main(String args[]) throws Exception {
//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");
//Loading the KeyStore object
char[] password = "changeit".toCharArray();
String path = "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts";
java.io.FileInputStream fis = new FileInputStream(path);
keyStore.load(fis, password);
//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);
//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec("myPassword".getBytes(), "DSA");
//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);
//Storing the KeyStore object
java.io.FileOutputStream fos = null;
fos = new java.io.FileOutputStream("newKeyStoreName");
keyStore.store(fos, password);
System.out.println("data stored");
}
}
Output
上述程序生成以下输出 −
System.out.println("data stored");
Java Cryptography - Retrieving keys
在本章中,我们将学习如何使用 Java 加密从 密钥库中检索密钥。
要从密钥库中检索密钥,请按照以下步骤操作。
Step 1: Create a KeyStore object
java.security 包中的 KeyStore 类的 getInstance() 方法接收一个表示密钥库类型的字符串值,并返回一个 KeyStore 对象。
使用此方法创建 KeyStore 类的对象,如下所示。
//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");
Step 2: Load the KeyStore object
KeyStore 类的 load() 方法接收一个表示密钥库文件的 FileInputStream 对象和一个指定 KeyStore 密码的字符串参数。
通常,密钥库存储在名为 cacerts 的文件中,位于 C:/Program Files/Java/jre1.8.0_101/lib/security/ 位置,其默认密码为 changeit ,可以使用 load() 方法加载,如下所示。
//Loading the KeyStore object
char[] password = "changeit".toCharArray();
String path = "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts";
java.io.FileInputStream fis = new FileInputStream(path);
keyStore.load(fis, password);
Step 3: Create the KeyStore.ProtectionParameter object
按如下所示实例化 KeyStore.ProtectionParameter。
//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);
Step 4: Create a SecretKey object
通过实例化其子类 SecretKeySpec 来创建 SecretKey (接口)对象。在实例化时,您需要将密码和算法作为参数传递给它的构造函数,如下所示。
//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec(new String(keyPassword).getBytes(), "DSA");
Step 5: Create a SecretKeyEntry object
通过传递在上述步骤中创建的 SecretKey 对象来创建 SecretKeyEntry 类的对象,如下所示。
//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);
Step 6: set an entry to the KeyStore
KeyStore 类的 setEntry() 方法接收一个表示密钥库条目别名的字符串参数、一个 SecretKeyEntry 对象和一个 ProtectionParameter 对象,并将条目存储在给定的别名下。
使用 setEntry() 方法将条目设置到密钥库,如下所示。
//Set the entry to the keystore
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);
Step 7: Create the KeyStore.SecretKeyEntry object
KeyStore 类的 getEntry() 方法接收一个别名(字符串参数)和一个 ProtectionParameter 类的对象作为参数,并返回一个 KeyStoreEntry 对象,然后您可以将其转换为 KeyStore.SecretKeyEntry 对象。
通过将所需密钥的别名和在先前步骤中创建的保护参数对象传递给 getEntry() 方法,创建 KeyStore.SecretKeyEntry 类的对象,如下所示。
//Creating the KeyStore.SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEnt = (KeyStore.SecretKeyEntry)keyStore.getEntry("secretKeyAlias", protectionParam);
Step 8: Create the key object of the retrieved entry
SecretKeyEntry 类的 getSecretKey() 方法返回一个 SecretKey 对象。使用此方法创建一个 SecretKey 对象,如下所示。
//Creating SecretKey object
SecretKey mysecretKey = secretKeyEnt.getSecretKey();
System.out.println(mysecretKey);
Example
以下示例演示了如何从密钥库中检索密钥。在此,我们将密钥存储在密钥库中(位于“cacerts”文件中(windows 10 操作系统)),检索它,并显示其一些属性,例如用于生成密钥的算法和检索的密钥的格式。
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.KeyStore.ProtectionParameter;
import java.security.KeyStore.SecretKeyEntry;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class RetrievingFromKeyStore{
public static void main(String args[]) throws Exception{
//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");
//Loading the the KeyStore object
char[] password = "changeit".toCharArray();
java.io.FileInputStream fis = new FileInputStream(
"C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts");
keyStore.load(fis, password);
//Creating the KeyStore.ProtectionParameter object
ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);
//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec("myPassword".getBytes(), "DSA");
//Creating SecretKeyEntry object
SecretKeyEntry secretKeyEntry = new SecretKeyEntry(mySecretKey);
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);
//Storing the KeyStore object
java.io.FileOutputStream fos = null;
fos = new java.io.FileOutputStream("newKeyStoreName");
keyStore.store(fos, password);
//Creating the KeyStore.SecretKeyEntry object
SecretKeyEntry secretKeyEnt = (SecretKeyEntry)keyStore.getEntry("secretKeyAlias", protectionParam);
//Creating SecretKey object
SecretKey mysecretKey = secretKeyEnt.getSecretKey();
System.out.println("Algorithm used to generate key : "+mysecretKey.getAlgorithm());
System.out.println("Format used for the key: "+mysecretKey.getFormat());
}
}
Java Cryptography - KeyGenerator
Java 提供 KeyGenerator 类,此类用于生成密钥并且此类的对象是可重复使用的。
要使用 KeyGenerator 类生成密钥,请按照以下给定的步骤进行操作。
Step 1: Create a KeyGenerator object
KeyGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyGenerator 对象。
使用所示方法 getInstance() 创建 KeyGenerator 对象,如下所示。
//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
Step 2: Create SecureRandom object
java.Security 包的 SecureRandom 类提供了一个强随机数发生器,用于在 Java 中生成随机数。Instantiate 此类,如下所示。
//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();
Step 3: Initialize the KeyGenerator
KeyGenerator 类提供一个名为 init() 的方法,此方法接受 SecureRandom 对象并初始化当前 KeyGenerator 。
使用 init() 方法初始化在上一步中创建的 KeyGenerator 对象。
//Initializing the KeyGenerator
keyGen.init(secRandom);
Example
以下示例演示如何使用 javax.crypto 包的 KeyGenerator 类生成密钥。
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
public class KeyGeneratorExample {
public static void main(String args[]) throws Exception{
//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();
//Initializing the KeyGenerator
keyGen.init(secRandom);
//Creating/Generating a key
Key key = keyGen.generateKey();
System.out.println(key);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(cipher.ENCRYPT_MODE, key);
String msg = new String("Hi how are you");
byte[] bytes = cipher.doFinal(msg.getBytes());
System.out.println(bytes);
}
}
Java Cryptography - KeyPairGenerator
Java 提供 KeyPairGenerator 类。此类用于生成公钥和私钥对。要使用 KeyPairGenerator 类生成密钥,请按照以下给定的步骤进行操作。
Step 1: Create a KeyPairGenerator object
KeyPairGenerator 类提供了 getInstance() 方法,该方法接受一个表示所需密钥生成算法的 String 变量,并返回一个生成密钥的 KeyPairGenerator 对象。
使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
Step 2: Initialize the KeyPairGenerator object
KeyPairGenerator 类提供一个名为 initialize() 的方法,此方法用于初始化密钥对生成器。此方法接受一个表示密钥大小的整数值。
使用所示方法初始化在上一步中创建的 KeyPairGenerator 对象,如下所示。
//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);
Step 3: Generate the KeyPairGenerator
您可以使用 KeyPairGenerator 类的 generateKeyPair() 方法生成 KeyPair 。使用此方法生成密钥对,如下所示。
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
Step 4: Get the private key/public key
可以使用 getPrivate() 方法,从生成的 KeyPair 对象获取私钥,如下所示。
//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();
您可以使用 getPublic() 方法从生成的 KeyPair 对象获取公钥,如下所示。
//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();
Example
以下示例演示如何使用 javax.crypto 包的 KeyPairGenerator 类生成密钥。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
public class KeyPairGenertor {
public static void main(String args[]) throws Exception{
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);
//Generating the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();
//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();
System.out.println("Keys generated");
}
}
Java Cryptography - Creating Signature
数字签名允许我们验证签名者的作者、日期和时间,验证消息内容的真实性。它还包括用于附加功能的身份验证功能。
Creating the digital signature
现在让我们学习如何创建数字签名。你可以按照以下步骤使用 Java 创建数字签名。
Step 1: Create a KeyPairGenerator object
KeyPairGenerator 类提供了 getInstance() 方法,该方法接受一个表示所需密钥生成算法的 String 变量,并返回一个生成密钥的 KeyPairGenerator 对象。
使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
Step 2: Initialize the KeyPairGenerator object
KeyPairGenerator 类提供一个名为 initialize() 的方法,此方法用于初始化密钥对生成器。此方法接受一个表示密钥大小的整数值。
使用 initialize() 方法初始化在前一步中创建的 KeyPairGenerator 对象,如下所示。
//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);
Step 3: Generate the KeyPairGenerator
你可以使用 generateKeyPair() 方法生成 KeyPair 。如下所示,使用 generateKeyPair() 方法生成密钥对。
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
Step 4: Get the private key from the pair
你可以使用 getPrivate() 方法从生成的 KeyPair 对象中获取私钥。
如下所示,使用 getPrivate() 方法获取私钥。
//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();
Step 5: Create a signature object
Signature 类的 getInstance() 方法接受一个表示所需的签名算法的字符串参数,并返回相应的签名对象。
使用 getInstance() 方法创建签名类的对象。
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");
Step 6: Initialize the Signature object
签名类的 initSign() 方法接受一个 PrivateKey 对象,并初始化当前签名对象。
如下所示,使用 initSign() 方法初始化在上一步中创建的签名对象。
//Initialize the signature
sign.initSign(privKey);
Step 7: Add data to the Signature object
update() 方法接受一个字节数组,用来表示待签名或验证的数据,并使用提供的数据更新当前对象。
使用下面的示例,通过将待签名数据以字节数组的形式传递给 update() 方法,来更新已初始化的 Signature 对象。
byte[] bytes = "Hello how are you".getBytes();
//Adding data to the signature
sign.update(bytes);
Step 8: Calculate the Signature
sign() 方法返回已更新数据的签名字节。
使用下面的示例,使用 sign() 方法计算签名。
//Calculating the signature
byte[] signature = sign.sign();
Example
以下 Java 程序接受一个来自用户的消息,并为给定消息生成数字签名。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Scanner;
public class CreatingDigitalSignature {
public static void main(String args[]) throws Exception {
//Accepting text from user
Scanner sc = new Scanner(System.in);
System.out.println("Enter some text");
String msg = sc.nextLine();
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
//Initializing the key pair generator
keyPairGen.initialize(2048);
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");
//Initialize the signature
sign.initSign(privKey);
byte[] bytes = "msg".getBytes();
//Adding data to the signature
sign.update(bytes);
//Calculating the signature
byte[] signature = sign.sign();
//Printing the signature
System.out.println("Digital signature for given text: "+new String(signature, "UTF8"));
}
}
Output
上述程序生成以下输出 −
Enter some text
Hi how are you
Digital signature for given text: 0=@gRD???-?.???? /yGL?i??a!?
Java Cryptography - Verifying Signature
您可以使用 Java 创建数字签名,并按照以下步骤对其进行验证。
Step 1: Create a KeyPairGenerator object
KeyPairGenerator 类提供了 getInstance() 方法,该方法接受一个表示所需密钥生成算法的 String 变量,并返回一个生成密钥的 KeyPairGenerator 对象。
使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
Step 2: Initialize the KeyPairGenerator object
KeyPairGenerator 类提供了一个名为 initialize() 的方法。该方法用于初始化密钥对生成器。该方法接受一个表示密钥大小的整数值。
使用 initialize() 方法初始化在前一步中创建的 KeyPairGenerator 对象,如下所示。
//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);
Step 3: Generate the KeyPairGenerator
您可以使用 generateKeyPair() 方法生成 KeyPair 。如下所示使用该方法生成密钥对。
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
Step 4: Get the private key from the pair
你可以使用 getPrivate() 方法从生成的 KeyPair 对象中获取私钥。
如下所示,使用 getPrivate() 方法获取私钥。
//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();
Step 5: Create a signature object
Signature 类的 getInstance() 方法接受一个表示所需的签名算法的字符串参数,并返回相应的签名对象。
使用 getInstance() 方法创建签名类的对象。
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");
Step 6: Initialize the Signature object
签名类的 initSign() 方法接受一个 PrivateKey 对象,并初始化当前签名对象。
如下所示,使用 initSign() 方法初始化在上一步中创建的签名对象。
//Initialize the signature
sign.initSign(privKey);
Step 7: Add data to the Signature object
update() 方法接受一个字节数组,用来表示待签名或验证的数据,并使用提供的数据更新当前对象。
使用下面的示例,通过将待签名数据以字节数组的形式传递给 update() 方法,来更新已初始化的 Signature 对象。
byte[] bytes = "Hello how are you".getBytes();
//Adding data to the signature
sign.update(bytes);
Step 8: Calculate the Signature
sign() 方法返回已更新数据的签名字节。
如下所示使用 sign() 方法计算签名。
//Calculating the signature
byte[] signature = sign.sign();
Step 9: Initialize the signature object for verification
要验证签名对象,您需要先使用 initVerify() 方法对其进行初始化,该方法接受一个 PublicKey 对象。
因此,如下所示使用 initVerify() 方法初始化签名对象以进行验证。
//Initializing the signature
sign.initVerify(pair.getPublic());
Step 10: Update the data to be verified
如下所示使用 update 方法使用待验证数据更新已初始化(用于验证)对象。
//Update the data to be verified
sign.update(bytes);
Step 11: Verify the Signature
Signature 类的 verify() 方法接受另一个签名对象并使用当前对象对其进行验证。如果匹配,则返回 true,否则返回 false。
使用以下所示的方法验证签名。
//Verify the signature
boolean bool = sign.verify(signature);
Example
以下 Java 程序接受来自用户的讯息,产生给定讯息的数字签名,并验证它。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Scanner;
public class SignatureVerification {
public static void main(String args[]) throws Exception{
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
//Initializing the key pair generator
keyPairGen.initialize(2048);
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
//Getting the privatekey from the key pair
PrivateKey privKey = pair.getPrivate();
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");
//Initializing the signature
sign.initSign(privKey);
byte[] bytes = "Hello how are you".getBytes();
//Adding data to the signature
sign.update(bytes);
//Calculating the signature
byte[] signature = sign.sign();
//Initializing the signature
sign.initVerify(pair.getPublic());
sign.update(bytes);
//Verifying the signature
boolean bool = sign.verify(signature);
if(bool) {
System.out.println("Signature verified");
} else {
System.out.println("Signature failed");
}
}
}
Java Cryptography - Encrypting Data
您可以使用 javax.crypto 包的 Cipher 类加密给定数据。按照以下步骤使用 Java 加密给定数据。
Step 1: Create a KeyPairGenerator object
KeyPairGenerator 类提供了 getInstance() 方法,该方法接受一个表示所需密钥生成算法的 String 变量,并返回一个生成密钥的 KeyPairGenerator 对象。
使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
Step 2: Initialize the KeyPairGenerator object
KeyPairGenerator 类提供一个名为 initialize() 的方法,此方法用于初始化密钥对生成器。此方法接受一个表示密钥大小的整数值。
使用 initialize() 方法初始化在前一步中创建的 KeyPairGenerator 对象,如下所示。
//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);
Step 3: Generate the KeyPairGenerator
您可以使用 KeyPairGenerator 类的 generateKeyPair() 方法生成 KeyPair 。使用此方法生成密钥对,如下所示。
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
Step 4: Get the public key
您可以使用 getPublic() 方法从生成的 KeyPair 对象中获取公钥,如下所示。
使用此方法获取公钥,如下所示。
//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();
Step 5: Create a Cipher object
Cipher 类的 getInstance() 方法接受一个表示所需转换的 String 变量,并返回实现给定转换的 Cipher 对象。
使用 getInstance() 方法创建 Cipher 对象,如下所示。
//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Step 6: Initialize the Cipher object
Cipher 类的 init() 方法接受两个参数,一个表示操作模式(加密/解密)的整型参数,以及一个表示公钥的 Key 对象。
使用 init() 方法初始化 Cypher 对象,如下所示。
//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
Step 7: Add data to the Cipher object
Cipher 类的 update() 方法接受一个表示要加密的数据的字节数组,并使用给定的数据更新当前对象。
通过以字节数组的形式将数据传递给 update() 方法,更新初始化的 Cipher 对象,如下所示。
//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();
cipher.update(input);
Step 8: Encrypt the data
Cipher 类的 doFinal() 方法完成加密操作。因此,使用此方法完成加密,如下所示。
//Encrypting the data
byte[] cipherText = cipher.doFinal();
Example
下面的 Java 程序接受来自用户的文本,使用 RSA 算法对其进行加密,并打印给定文本的加密格式。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
public class CipherSample {
public static void main(String args[]) throws Exception{
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withRSA");
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//Initializing the key pair generator
keyPairGen.initialize(2048);
//Generating the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, pair.getPublic());
//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();
cipher.update(input);
//encrypting the data
byte[] cipherText = cipher.doFinal();
System.out.println(new String(cipherText, "UTF8"));
}
}
Java Cryptography - Decrypting Data
您可以使用 javax.crypto 包的 Cipher 类解密加密数据。按照以下步骤使用 Java 解密给定数据。
Step 1: Create a KeyPairGenerator object
KeyPairGenerator 类提供了 getInstance() 方法,该方法接受一个表示所需密钥生成算法的 String 变量,并返回一个生成密钥的 KeyPairGenerator 对象。
使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
Step 2: Initialize the KeyPairGenerator object
KeyPairGenerator 类提供一个名为 initialize() 的方法,此方法用于初始化密钥对生成器。此方法接受一个表示密钥大小的整数值。
使用 initialize() 方法初始化在前一步中创建的 KeyPairGenerator 对象,如下所示。
//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);
Step 3: Generate the KeyPairGenerator
您可以使用 KeyPairGenerator 类的 generateKeyPair() 方法生成 KeyPair 。使用此方法生成密钥对,如下所示。
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
Step 4: Get the public key
您可以使用 getPublic() 方法从生成的 KeyPair 对象获取公钥,如下所示。
//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();
Step 5: Create a Cipher object
Cipher 类的 getInstance() 方法接受一个表示所需转换的 String 变量,并返回实现给定转换的 Cipher 对象。
使用 getInstance() 方法创建 Cipher 对象,如下所示。
//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Step 6: Initialize the Cipher object
Cipher 类的 init() 方法接受两个参数
-
表示操作模式的整数参数(加密/解密)
-
表示公钥的关键对象
使用 init() 方法初始化 Cypher 对象,如下所示。
//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
Step 7: Add data to the Cipher object
Cipher 类的 update() 方法接受一个表示要加密的数据的字节数组,并使用给定的数据更新当前对象。
通过以字节数组的形式将数据传递给 update() 方法,更新初始化的 Cipher 对象,如下所示。
//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();
cipher.update(input);
Step 8: Encrypt the data
Cipher 类的 doFinal() 方法完成加密操作。因此,使用此方法完成加密,如下所示。
//Encrypting the data
byte[] cipherText = cipher.doFinal();
Step 9: Initialize the Cipher object for decryption
要解密在上一步加密的密码,您需要对其进行解密初始化。
因此,通过传递参数 Cipher.DECRYPT_MODE 和 PrivateKey 对象对密码对象进行初始化,如下所示。
//Initializing the same cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());
Step 10: Decrypt the data
最后,使用 doFinal() 方法解密加密文本,如下所示。
//Decrypting the text
byte[] decipheredText = cipher.doFinal(cipherText);
Example
以下 Java 程序接收用户的文本,使用 RSA 算法对其进行加密,并打印给定文本的密码,解密密码并再次打印解密文本。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import javax.crypto.Cipher;
public class CipherDecrypt {
public static void main(String args[]) throws Exception{
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withRSA");
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//Initializing the key pair generator
keyPairGen.initialize(2048);
//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();
//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//Add data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();
cipher.update(input);
//encrypting the data
byte[] cipherText = cipher.doFinal();
System.out.println( new String(cipherText, "UTF8"));
//Initializing the same cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());
//Decrypting the text
byte[] decipheredText = cipher.doFinal(cipherText);
System.out.println(new String(decipheredText));
}
}
Output
上述程序生成以下输出 −
Encrypted Text:
]/[?F3?D?p
v?w?!?H???^?A??????P?u??FA?
?
???_?? ???_jMH-??>??OP?'?j?_?n`
?_??'`????o??_GL??g???g_f?????f|???LT?|?Vz_TDu#??\?<b,,?$C2???Bq?#?lDB`??g,^??K?_?v???`}
?;LX?a?_5e???#???_?6?/B&B_???^?__Ap^#_?q?IEh????_?,??*??]~_?_?D?
_y???lp??a?P_U{
Decrypted Text:
Welcome to Tutorialspoint