Java Cryptography 简明教程

Java Cryptography - Quick Guide

Java Cryptography - Introduction

密码学是制造能够提供信息安全的密码系统的艺术和科学。

密码学处理数字数据的实际安全保护。它指的是基于数学算法设计的机制,这些机制提供基本的信息安全服务。您可以将密码学视作一个包含安全应用程序中不同技术的大型工具包。

What is Cryptanalysis?

破解密文文本的艺术和科学被称为密码分析。

密码分析是密码学的一个相关分支,两者共存。密码过程生成密文文本用于传输或存储。它涉及学习密码机制以破解它们。密码分析还用于设计新密码技术来测试其安全强度。

Cryptography Primitives

密码原语只是密码学中的工具和技术,它们可以选择性地用于提供一组所需的安全性服务 −

  1. Encryption

  2. Hash functions

  3. Message Authentication codes (MAC)

  4. Digital Signatures

Cryptography in Java

Java 密码体系结构 (JCA) 是一组 API,用于实现现代密码学概念,如数字签名、消息摘要、证书、加密、密钥生成和管理以及安全随机数生成等。

使用 JCA,开发者可以构建应用程序,并在其中集成安全性。

为了在应用程序中集成安全性,您可以轻松调用 JCA 中为所需服务提供的相应 API,而不必依赖于复杂的安全性算法。

Java Cryptography - Message Digest

哈希函数非常有用,并且出现在几乎所有信息安全应用程序中。

哈希函数是一种数学函数,它将数字输入值转换成另一个压缩数字值。哈希函数的输入长度是任意的,但输出总是固定长度。

哈希函数返回的值称为 message digest 或简单称为 hash values 。下图为哈希函数的插图。

message digest

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());
   }
}

Output

上述程序生成以下输出 −

Enter the message
Hello how are you
[B@55f96302
Hex format: 2953d33828c395aebe8225236ba4e23fa75e6f13bd881b9056a3295cbd64d3

Java Cryptography - Creating a MAC

MAC(消息认证码)算法是对称密钥加密技术,用来提供消息认证。为了建立 MAC 流程,发送者和接收者共享对称密钥 K。

本质上,MAC 是在底层消息上生成的一种加密校验和,它与消息一起发送,以确保消息认证。

使用 MAC 进行认证的过程如下图所示 −

creating 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));
   }
}

Output

上面的程序将生成以下输出 −

Mac result:
HÖ„^ǃÎ_Utbh…?š_üzØSSÜh_ž_œa0ŽV?

Java Cryptography - Keys

密码体制是密码技术及其伴随基础设施的实现,用来提供信息安全服务。密码体制也被称为 cipher system

基本密码体制的各种部件包括 Plaintext, Encryption Algorithm, Ciphertext, Decryption Algorithm, 加密密钥和解密密钥。

其中,

  1. Encryption Key 是发送者知道的值。发送者将加密密钥与明文一起输入到加密算法中,以计算密文。

  2. Decryption Key 是接收者知道的值。解密密钥与加密密钥相关,但并不总是相同的值。接收者将解密密钥与密文一起输入到解密算法中,以计算密文。

从本质上讲,基于加密/解密算法的类型,有两种类型的密钥/密码体制。

Symmetric Key Encryption

加密过程中, same keys are used for encrypting and decrypting 信息称为对称密钥加密。

对称密码体制的研究被称为 symmetric cryptography 。对称密码体制有时也称为 secret key cryptosystems

以下是对称密钥加密的一些常见示例 −

  1. Digital Encryption Standard (DES)

  2. Triple-DES (3DES)

  3. IDEA

  4. BLOWFISH

Asymmetric Key Encryption

加密过程中, different keys are used for encrypting and decrypting the information 称为非对称密钥加密。尽管密钥不同,但它们在数学上是相关的,因此,通过解密密文来检索明文是可行的。

Java Cryptography - Storing keys

使用的/生成的密钥和证书存储在名为密钥库的数据库中。默认情况下,此数据库存储在名为 .keystore 的文件中。

您可以使用 java.security 包的 KeyStore 类访问此数据库的内容。这管理三个不同的条目,即 PrivateKeyEntry、SecretKeyEntry、TrustedCertificateEntry。

  1. PrivateKeyEntry

  2. SecretKeyEntry

  3. 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());
   }
}

Output

上述程序生成以下输出 −

Algorithm used to generate key: DSA
Format of the key: RAW

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);
   }
}

Output

上述程序生成以下输出 −

com.sun.crypto.provider.DESKey@18629
[B@2ac1fdc4

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");
   }
}

Output

上述程序生成以下输出 −

Keys generated

Java Cryptography - Creating Signature

数字签名允许我们验证签名者的作者、日期和时间,验证消息内容的真实性。它还包括用于附加功能的身份验证功能。

creating signature

Advantages of digital signature

在本节中,我们将了解需要使用数字签名的不同原因。在通信中实现数字签名的原因有几个:

Authentication

数字签名有助于验证消息的来源。例如,如果银行的分行向总行发送消息,要求更改账户余额。如果总行无法验证该消息是由授权来源发送的,则根据此类请求采取行动可能会犯下严重错误。

Integrity

一旦对消息签名,则消息中的任何更改都会使签名失效。

Non-repudiation

通过此属性,任何签署某些信息的实体在以后都不能否认已签署。

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");
      }
   }
}

Output

上述程序生成以下输出 −

Signature verified

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"));
   }
}

Output

上述程序生成以下输出 −

Encrypted Text:
"???:]J_?]???;Xl??????*@??u???r??=T&???_?_??.??i?????(?$_f?zD??????ZGH??g???
g?E:_??bz^??f?~o???t?}??u=uzp\UI????Z??l[?G?3??Y?UAEfKT?f?O??N_?d__?????a_?15%?^?
'p?_?$,9"{??^??y??_?t???,?W?PCW??~??[?$??????e????f?Y-Zi__??_??w?_?&QT??`?`~?[?K_??_???

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() 方法接受两个参数

  1. 表示操作模式的整数参数(加密/解密)

  2. 表示公钥的关键对象

使用 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