Java 密码学 - 快速指南


Java 密码学 - 简介

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

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

什么是密码分析?

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

密码分析是密码学的姊妹分支,两者共存。加密过程产生用于传输或存储的密文。它涉及对密码机制的研究,目的是破解它们。在新密码技术的设计过程中也使用密码分析来测试其安全强度。

密码学原语

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

  • 加密
  • 哈希函数
  • 消息验证码 (MAC)
  • 数字签名

Java 中的密码学

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

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

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

Java 密码学 - 消息摘要

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

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

哈希函数返回的值称为消息摘要或简称为哈希值。下图说明了哈希函数。

信息摘要

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:生成消息摘要

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

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

byte[] digest = md.digest();

例子

以下是从文件读取数据并生成消息摘要并打印它的示例。

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

输出

上述程序生成以下输出 -

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

Java 密码学 - 创建 MAC

MAC(消息认证)算法是一种提供消息认证的对称密钥加密技术为了建立MAC过程,发送方和接收方共享对称密钥K。

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

使用 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类提供了一个名为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);

例子

以下示例演示了使用 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));     
   }
}

输出

上述程序将生成以下输出 -

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

Java 密码学 - 密钥

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

基本密码系统的各个组成部分是明文、加密算法、密文、解密算法、加密密钥和解密密钥。

在哪里,

  • 加密密钥是发送者已知的值。发送者将加密密钥与明文一起输入加密算法中,以计算密文。

  • 解密密钥是接收者已知的值。解密密钥与加密密钥相关,但并不总是相同。接收方将解密密钥与密文一起输入解密算法,以计算明文。

基本上,根据加密解密算法的类型,有两种类型的密钥/密码系统。

对称密钥加密

使用相同的密钥来加密和解密信息的加密过程称为对称密钥加密。

对对称密码系统的研究称为对称密码学。对称密码系统有时也称为秘密密钥密码系统

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

  • 数字加密标准 (DES)
  • 三重 DES (3DES)
  • 主意
  • 河豚

非对称密钥加密

使用不同密钥来加密和解密信息的加密过程称为非对称密钥加密。尽管密钥不同,但它们在数学上是相关的,因此通过解密密文来检索明文是可行的。

Java 密码学 - 存储密钥

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

您可以使用java.security包的KeyStore类访问此数据库的内容。它管理三个不同的条目,即 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);

第四步:创建SecretKey对象

通过实例化其子类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);

例子

以下示例将密钥存储到“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");
   }
}

输出

上述程序生成以下输出 -

System.out.println("data stored");

Java 密码学 - 检索密钥

在本章中,我们将学习如何使用 Java 加密技术从密钥库中检索密钥。

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

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

第四步:创建SecretKey对象

通过实例化其子类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 ()方法接受别名(字符串参数)和 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);

例子

以下示例演示如何从密钥存储中检索密钥。在这里,我们将密钥存储在密钥库中,该密钥库位于“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());
   }
}

输出

上述程序生成以下输出 -

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

Java 密码学 - 密钥生成器

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类提供了一个名为init()的方法,该方法接受SecureRandom对象并初始化当前的KeyGenerator

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

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

例子

以下示例演示了使用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);      
   }
}

输出

上述程序生成以下输出 -

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

Java 密码学 - KeyPairGenerator

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

第四步:获取私钥/公钥

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

例子

以下示例演示了使用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");
   }
}

输出

上述程序生成以下输出 -

Keys generated

Java 密码学 - 创建签名

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

创建签名

数字签名的优点

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

验证

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

正直

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

不可否认性

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

创建数字签名

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

第 1 步:创建 KeyPairGenerator 对象

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

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

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

步骤 2:初始化 KeyPairGenerator 对象

KeyPairGenerator类提供了一个名为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()方法来更新初始化的 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();

例子

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

输出

上述程序生成以下输出 -

Enter some text
Hi how are you
Digital signature for given text: 0=@gRD???-?.???? /yGL?i??a!?

Java 密码学 - 验证签名

您可以使用 Java 创建数字签名并按照以下步骤进行验证。

第 1 步:创建 KeyPairGenerator 对象

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

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

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

步骤 2:初始化 KeyPairGenerator 对象

KeyPairGenerator类提供一个名为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()方法来更新初始化的 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 方法用要验证的数据更新初始化(用于验证)对象,如下所示。

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

第11步:验证签名

Signature 类的 verify() 方法接受另一个签名对象并用当前签名对象进行验证如果匹配,则返回 true,否则返回 false。

使用此方法验证签名,如下所示。

//Verify the signature
boolean bool = sign.verify(signature);

例子

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

输出

上述程序生成以下输出 -

Signature verified

Java 密码学 - 加密数据

您可以使用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()方法初始化在上一步中创建的KeyPairGenerator 对象,如下所示。

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

第 3 步:生成 KeyPairGenerator

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

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

第四步:获取公钥

您可以使用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()方法来更新初始化的 Cipher 对象,如下所示。

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

第 8 步:加密数据

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

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

例子

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

输出

上述程序生成以下输出 -

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 密码学 - 解密数据

您可以使用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()方法初始化在上一步中创建的KeyPairGenerator 对象,如下所示。

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

第 3 步:生成 KeyPairGenerator

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

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

第四步:获取公钥

您可以使用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()方法来更新初始化的 Cipher 对象,如下所示。

//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".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);

例子

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

输出

上述程序生成以下输出 -

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