Java Cryptography - 快速指南

本文详细介绍了Java密码学中的关键概念,包括使用MessageDigest生成消息摘要,创建和使用MAC进行消息认证,以及如何在KeyStore中存储和检索密钥。此外,还讨论了加密和解密过程,以及如何使用Cipher类进行数据加解密。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文连接

步骤 6:设置 KeyStore 的条目 KeyStore 类的 setEntry() 方法接受表示密钥库条目别名的 String 参数, SecretKeyEntry 对象,ProtectionParameter 对象,并将条目存储在给定别名下。

  1. WIKI 教程
  2. 学习 Java 密码学
  3. Java Cryptography - 快速指南

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

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

什么是密码分析?

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

密码分析是密码学的姐妹分支,它们共存。 加密过程产生用于传输或存储的密文。 它涉及密码机制的研究,旨在打破它们。 在设计新的加密技术时也使用密码分析来测试它们的安全性。

密码学原语

密码学原语只不过是密码学中可以有选择地用于提供一组所需安全服务的工具和技术 -

  • Encryption
  • 散列函数
  • 消息验证码(MAC)
  • 数字签名

Java 中的密码学

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

使用 JCA 开发人员可以构建集成安全性的应用程序。

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

散列函数非常有用,几乎出现在所有信息安全应用程序中。

哈希函数是将数字输入值转换为另一个压缩数值的数学函数。 散列函数的输入具有任意长度,但输出始终具有固定长度。

散列函数返回的值称为 message digest 或简称 hash values 。 下图说明了散列函数。

Java 提供了一个名为 MessageDigest 的类,它属于 java.security 包。 此类支持诸如 SHA-1,SHA 256,MD5 算法之类的算法,以将任意长度的消息转换为消息摘要。

要将给定邮件转换为邮件摘要,请按照以下步骤进行操作 -

第 1 步: 创建 MessageDigest 对象

MessageDigest 类提供了一个名为 getInstance() 的方法。 此方法接受 String 变量,该变量指定要使用的算法的名称,并返回实现指定算法的 MessageDigest 对象。

使用 getInstance() 方法创建 MessageDigest 对象,如下所示。

MessageDigest md = MessageDigest.getInstance("SHA-256");

第 2 步: 将数据传递给创建的 MessageDigest 对象

创建消息摘要对象后,需要将消息 / 数据传递给它。 您可以使用 MessageDigest 类的 update() 方法执行此操作,此方法接受表示消息的字节数组,并将其添加 / 传递给上面创建的 MessageDigest 对象。

md.update(msg.getBytes());

第 3 步: 生成消息摘要

您可以使用 digest() 方法生成消息摘要,MessageDigest 类此方法计算当前对象的散列函数,并以字节数组的形式返回消息摘要。

使用摘要方法生成消息摘要。

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

MAC( M essage A uessntication C ode)算法是一种对称密钥加密技术,用于提供消息认证。 为了建立 MAC 过程,发送方和接收方共享对称密钥 K.

实质上,MAC 是在基础消息上生成的加密校验和,它与消息一起发送以确保消息验证。

使用 MAC 进行身份验证的过程如下图所示 -

在 Java 中, javax.crypto 包的 Mac 类提供了消息认证代码的功能。 按照以下步骤使用此类创建消息身份验证代码。

第 1 步: 创建 KeyGenerator 对象

KeyGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyGenerator 对象。

使用 getInstance() 方法创建 KeyGenerator 对象,如下所示。

//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");

第 2 步: 创建 SecureRandom 对象

java.Security 包的 SecureRandom 类提供了一个强大的随机数生成器,用于在 Java 中生成随机数。 实例化此类,如下所示。

//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();

第 3 步: 初始化 KeyGenerator

KeyGenerator 类提供了一个名为 init() 方法,此方法接受 SecureRandom 对象并初始化当前的 KeyGenerator

使用此方法初始化在上一步中创建的 KeyGenerator 对象。

//Initializing the KeyGenerator
keyGen.init(secRandom);

第 4 步: 生成密钥

使用 KeyGenerator 类的 generateKey() 方法生成密钥,如下所示。

//Creating/Generating a key
Key key = keyGen.generateKey();

第 5 步: 初始化 Mac 对象

Mac 类的 init() 方法接受 Key 对象并使用给定的键初始化当前的 Mac 对象。

//Initializing the Mac object
mac.init(key);

第 6 步: 完成 mac 操作

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 生成消息验证代码(MAC)。 在这里,我们收到一条简单的消息 “你好,你好”,并为该消息生成一个 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?

密码系统是加密技术及其附带基础设施的实现,以提供信息安全服务。 密码系统也称为 cipher system

基本密码系统的各种组件是 Plaintext, Encryption Algorithm, Ciphertext, Decryption Algorithm, 加密密钥和解密密钥。

Where,

  • Encryption Key 是发件人已知的值。 发送方将加密密钥与明文一起输入加密算法,以便计算密文。

  • Decryption Key 是接收方已知的值。 解密密钥与加密密钥有关,但并不总是与之相同。 接收器将解密密钥与密文一起输入到解密算法中以便计算明文。

基本上,基于加密 - 解密算法的类型,存在两种类型的密钥 / 密码系统。

对称密钥加密

使用 same keys are used for encrypting and decrypting 信息的加密过程称为对称密钥加密。

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

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

  • 数字加密标准(DES)
  • 三重 DES(3DES)
  • IDEA
  • BLOWFISH

非对称密钥加密

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

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

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

  • PrivateKeyEntry
  • SecretKeyEntry
  • TrustedCertificateEntry

在密钥库中存储密钥

在本节中,我们将学习如何在密钥库中存储密钥。 要在密钥库中存储密钥,请按照以下步骤操作。

第 1 步: 创建 KeyStore 对象

java.security 包的 KeyStore 类的 getInstance() 方法接受表示密钥库类型的字符串值,并返回 KeyStore 对象。

使用 getInstance() 方法创建 KeyStore 类的对象,如下所示。

//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");

第 2 步: 加载 KeyStore 对象

KeyStore 类的 load() 方法接受表示密钥库文件的 FileInputStream 对象和指定 KeyStore 密码的 String 参数。

通常,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);

第 3 步: 创建 KeyStore.ProtectionParameter 对象

实例化 KeyStore.ProtectionParameter,如下所示。

//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);

第 4 步: 创建一个 SecretKey 对象

通过实例化其 Sub 类 SecretKeySpec 创建 SecretKey (接口)对象。 在实例化时,您需要将密码和算法作为参数传递给其构造函数,如下所示。

//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec(new String(keyPassword).getBytes(), "DSA");

第 5 步: 创建一个 SecretKeyEntry 对象

通过传递在上面步骤中创建的 SecretKey 对象来创建 SecretKeyEntry 类的对象,如下所示。

//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);

步骤 6: 设置 KeyStore 的条目

KeyStore 类的 setEntry() 方法接受表示密钥库条目别名的 String 参数, 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 从密钥库中检索密钥。

要从密钥库中检索密钥,请按照以下步骤操作。

第 1 步: 创建 KeyStore 对象

java.security 包的 KeyStore 类的 getInstance() 方法接受表示密钥库类型的字符串值,并返回 KeyStore 对象。

使用此方法创建 KeyStore 类的对象,如下所示。

//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");

第 2 步: 加载 KeyStore 对象

KeyStore 类的 load() 方法接受表示密钥库文件的 FileInputStream 对象和指定 KeyStore 密码的 String 参数。

通常,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);

第 3 步: 创建 KeyStore.ProtectionParameter 对象

实例化 KeyStore.ProtectionParameter,如下所示。

//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);

第 4 步: 创建一个 SecretKey 对象

通过实例化其 Sub 类 SecretKeySpec 创建 SecretKey (接口)对象。 在实例化时,您需要将密码和算法作为参数传递给其构造函数,如下所示。

//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec(new String(keyPassword).getBytes(), "DSA");

第 5 步: 创建一个 SecretKeyEntry 对象

通过传递在上面步骤中创建的 SecretKey 对象来创建 SecretKeyEntry 类的对象,如下所示。

//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);

第 6 步: 设置 KeyStore 的条目

KeyStore 类的 setEntry() 方法接受表示密钥库条目别名的 String 参数, SecretKeyEntry 对象,ProtectionParameter 对象,并将条目存储在给定别名下。

使用 setEntry() 方法将条目设置为密钥库,如下所示。

//Set the entry to the keystore
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);

第 7 步: 创建 KeyStore.SecretKeyEntry 对象

KeyStore 类的 getEntry() 方法接受别名(String 参数),并将 ProtectionParameter 类的对象作为参数,并返回 KeyStoreEntry 对象,然后将其转换为 KeyStore.SecretKeyEntry 对象。

通过将必需键的别名和前面步骤中创建的保护参数对象传递给 getEntry() 方法,创建 KeyStore.SecretKeyEntry 类的对象,如下所示。

//Creating the KeyStore.SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEnt = (KeyStore.SecretKeyEntry)keyStore.getEntry("secretKeyAlias", protectionParam);

步骤 8: 创建检索到的条目的密钥对象

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 提供了 KeyGenerator 类,该类用于生成密钥,此类的对象是可重用的。

要使用 KeyGenerator 类生成密钥,请按照以下步骤操作。

第 1 步: 创建 KeyGenerator 对象

KeyGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyGenerator 对象。

使用 getInstance() 方法创建 KeyGenerator 对象,如下所示。

//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");

第 2 步: 创建 SecureRandom 对象

java.Security 包的 SecureRandom 类提供了一个强大的随机数生成器,用于在 Java 中生成随机数。 实例化此类,如下所示。

//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();

第 3 步: 初始化 KeyGenerator

KeyGenerator 类提供了一个名为 init() 方法,此方法接受 SecureRandom 对象并初始化当前的 KeyGenerator

使用 init() 方法 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 提供了 KeyPairGenerator 类。 此类用于生成公钥和私钥对。 要使用 KeyPairGenerator 类生成密钥,请按照以下步骤操作。

第 1 步: 创建 KeyPairGenerator 对象

KeyPairGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyPairGenerator 对象。

使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

第 2 步: 初始化 KeyPairGenerator 对象

KeyPairGenerator 类提供了一个名为 initialize() 方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。

使用此方法初始化在上一步中创建的 KeyPairGenerator 对象,如下所示。

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

第 3 步: 生成 KeyPairGenerator

您可以使用 KeyPairGenerator 类的 generateKeyPair() 方法生成 KeyPair 。 使用此方法生成密钥对,如下所示。

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

第 4 步: 获取私钥 / 公钥

您可以使用 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

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

数字签名的优点

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

身份验证 (Authentication)

数字签名有助于验证消息来源。 例如,如果银行的分支机构向中央办公室发送消息,请求更改帐户余额。 如果中央办公室无法验证从授权来源发送的消息,则执行此类请求可能是一个严重的错误。

完整性 (Integrity)

邮件签名后,邮件中的任何更改都将使签名无效。

Non-repudiation

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

创建数字签名

现在让我们学习如何创建数字签名。 您可以按照以下步骤使用 Java 创建数字签名。

第 1 步: 创建 KeyPairGenerator 对象

KeyPairGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyPairGenerator 对象。

使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

第 2 步: 初始化 KeyPairGenerator 对象

KeyPairGenerator 类提供了一个名为 initialize() 方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。

使用 initialize() 方法 initialize() 在上一步中创建的 KeyPairGenerator 对象,如下所示。

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

第 3 步: 生成 KeyPairGenerator

您可以使用 generateKeyPair() 方法生成 KeyPair 。 使用 generateKeyPair() 方法生成密钥对,如下所示。

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

第 4 步: 从对中获取私钥

您可以使用 getPrivate() 方法从生成的 KeyPair 对象中获取私钥。

使用 getPrivate() 方法获取私钥,如下所示。

//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();

第 5 步: 创建签名对象

Signature 类的 getInstance() 方法接受表示所需签名算法的字符串参数,并返回相应的 Signature 对象。

使用 getInstance() 方法创建 Signature 类的对象。

//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");

第 6 步: 初始化 Signature 对象

Signature 类的 initSign() 方法接受 PrivateKey 对象并初始化当前的 Signature 对象。

使用 initSign() 方法初始化在上一步中创建的 Signature 对象,如下所示。

//Initialize the signature
sign.initSign(privKey);

第 7 步: 将数据添加到 Signature 对象

Signature 类的 update() 方法接受表示要签名或验证的数据的字节数组,并使用给定的数据更新当前对象。

通过以字节数组的形式将要签名的数据传递给 update() 方法来 update() 初始化的 Signature 对象,如下所示。

byte[] bytes = "Hello how are you".getBytes();      
//Adding data to the signature
sign.update(bytes);

第 8 步: 计算签名

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 创建数字签名,并按照以下步骤进行验证。

第 1 步: 创建 KeyPairGenerator 对象

KeyPairGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyPairGenerator 对象。

使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

第 2 步: 初始化 KeyPairGenerator 对象

KeyPairGenerator 类提供了一个名为 initialize() 方法的方法。 此方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。

使用 initialize() 方法 initialize() 在上一步中创建的 KeyPairGenerator 对象,如下所示。

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

第 3 步: 生成 KeyPairGenerator

您可以使用 generateKeyPair() 方法生成 KeyPair 。 使用此方法生成密钥对,如下所示。

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

第 4 步: 从对中获取私钥

您可以使用 getPrivate() 方法从生成的 KeyPair 对象中获取私钥。

使用 getPrivate() 方法获取私钥,如下所示。

//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();

第 5 步: 创建签名对象

Signature 类的 getInstance() 方法接受表示所需签名算法的字符串参数,并返回相应的 Signature 对象。

使用 getInstance() 方法创建 Signature 类的对象。

//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");

第 6 步: 初始化 Signature 对象

Signature 类的 initSign() 方法接受 PrivateKey 对象并初始化当前的 Signature 对象。

使用 initSign() 方法初始化在上一步中创建的 Signature 对象,如下所示。

//Initialize the signature
sign.initSign(privKey);

第 7 步: 将数据添加到 Signature 对象

Signature 类的 update() 方法接受表示要签名或验证的数据的字节数组,并使用给定的数据更新当前对象。

通过以字节数组的形式将要签名的数据传递给 update() 方法来 update() 初始化的 Signature 对象,如下所示。

byte[] bytes = "Hello how are you".getBytes();      
//Adding data to the signature
sign.update(bytes);

第 8 步: 计算签名

Signature 类的 sign() 方法返回更新数据的签名字节。

使用 sign()方法计算签名,如下所示。

//Calculating the signature
byte[] signature = sign.sign();

步骤 9: 初始化签名对象以进行验证

要验证 Signature 对象,首先需要使用 initVerify() 方法对其进行初始化,该方法接受 PublicKey 对象。

因此,使用 initVerify() 方法初始化 Signature 对象以进行验证,如下所示。

//Initializing the signature
sign.initVerify(pair.getPublic());

步骤 10: 更新要验证的数据

使用更新方法使用要验证的数据更新初始化(用于验证)对象,如下所示。

//Update the data to be verified
sign.update(bytes);

步骤 11: 验证签名

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

您可以使用 javax.crypto 包的 Cipher 类加密给定数据。 按照下面给出的步骤使用 Java 加密给定的数据。

第 1 步: 创建 KeyPairGenerator 对象

KeyPairGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyPairGenerator 对象。

使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

第 2 步: 初始化 KeyPairGenerator 对象

KeyPairGenerator 类提供了一个名为 initialize() 方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。

使用 initialize() 方法 initialize() 在上一步中创建的 KeyPairGenerator 对象,如下所示。

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

第 3 步: 生成 KeyPairGenerator

您可以使用 KeyPairGenerator 类的 generateKeyPair() 方法生成 KeyPair 。 使用此方法生成密钥对,如下所示。

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

第 4 步: 获取公钥

您可以使用 getPublic() 方法从生成的 KeyPair 对象获取公钥,如下所示。

使用此方法获取公钥,如下所示。

//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();

第 5 步: 创建一个 Cipher 对象

Cipher 类的 getInstance() 方法接受表示所需转换的 String 变量,并返回实现给定转换的 Cipher 对象。

使用 getInstance() 方法创建 Cipher 对象,如下所示。

//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

步骤 6: 初始化 Cipher 对象

Cipher 类的 init() 方法接受两个参数,一个表示操作模式的整数参数(加密 / 解密)和一个表示公钥的 Key 对象。

使用 init() 方法初始化 Cypher 对象,如下所示。

//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

步骤 7: 将数据添加到 Cipher 对象

Cipher 类的 update() 方法接受表示要加密的数据的字节数组,并使用给定的数据更新当前对象。

通过以字节数组的形式将数据传递给 update() 方法来 update() 初始化的 Cipher 对象,如下所示。

//Adding data to the cipher
byte[] input = "Welcome to IoWiki".getBytes();	  
cipher.update(input);

第 8 步: 加密数据

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 IoWiki".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_??_? ??

您可以使用 javax.crypto 包的 Cipher 类解密加密数据。 按照下面给出的步骤使用 Java 解密给定数据。

第 1 步: 创建 KeyPairGenerator 对象

KeyPairGenerator 类提供 getInstance() 方法,该方法接受表示所需密钥生成算法的 String 变量,并返回生成密钥的 KeyPairGenerator 对象。

使用 getInstance() 方法创建 KeyPairGenerator 对象,如下所示。

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

第 2 步: 初始化 KeyPairGenerator 对象

KeyPairGenerator 类提供了一个名为 initialize() 方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。

使用 initialize() 方法 initialize() 在上一步中创建的 KeyPairGenerator 对象,如下所示。

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

第 3 步: 生成 KeyPairGenerator

您可以使用 KeyPairGenerator 类的 generateKeyPair() 方法生成 KeyPair 。 使用此方法生成密钥对,如下所示。

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

第 4 步: 获取公钥

您可以使用 getPublic() 方法从生成的 KeyPair 对象获取公钥,如下所示。

//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();

第 5 步: 创建一个 Cipher 对象

Cipher 类的 getInstance() 方法接受表示所需转换的 String 变量,并返回实现给定转换的 Cipher 对象。

使用 getInstance() 方法创建 Cipher 对象,如下所示。

//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

步骤 6: 初始化 Cipher 对象

Cipher 类的 init() 方法接受两个参数

  • 表示操作模式的整数参数(加密 / 解密)
  • 表示公钥的关键对象

使用 init() 方法初始化 Cypher 对象,如下所示。

//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

步骤 7: 将数据添加到 Cipher 对象

Cipher 类的 update() 方法接受表示要加密的数据的字节数组,并使用给定的数据更新当前对象。

通过以字节数组的形式将数据传递给 update() 方法来 update() 初始化的 Cipher 对象,如下所示。

//Adding data to the cipher
byte[] input = "Welcome to IoWiki".getBytes();	  
cipher.update(input);

第 8 步: 加密数据

Cipher 类的 doFinal() 方法完成加密操作。 因此,使用此方法完成加密,如下所示。

//Encrypting the data
byte[] cipherText = cipher.doFinal();

步骤 9: 初始化 Cipher 对象以进行解密

要解密前面步骤中加密的密码,您需要初始化它以进行解密。

因此,通过传递参数 Cipher.DECRYPT_MODE 和 PrivateKey 对象来初始化密码对象,如下所示。

//Initializing the same cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());

第 10 步: 解密数据

最后,使用 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 IoWiki".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 IoWiki
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值