jenkov.tutorials系列(Java加密与解密的具体使用)

Java Keystore教程 目录 1.简介 2. SSL及其工作方式 3.私钥 4.公开证书 5.根证书 6.证书颁发机构 7.证书链 8.使用Java keytool的密钥库 9.密钥库命令 10.在Apache Tomcat上使用密钥库和自签名证书配置SSL 1.简介 我们谁没有去ebay,亚马逊买东西或他的个人银行帐户来检查。 您是否认为这些站点足够安全,可以... 阅读详情

jenkov.tutorials系列(Java加密与解密的具体使用)

Java Cipher(javax.crypto.Cipher)类表示一种加密算法。 密码这一术语是密码学领域中加密算法的标准术语。 这就是为什么Java类称为Cipher而不是例如 加密器/解密器或其他东西。

创建Cipher

在使用Java Cipher之前,您只需创建Cipher类的实例。 通过调用带有参数的getInstance()方法来创建一个Cipher实例,该参数告诉您要使用哪种类型的加密算法。 这是创建Java Cipher实例的示例:

Cipher cipher = Cipher.getInstance("AES");

模式选择

某些加密算法可以在不同的模式下工作。 加密模式指定有关算法应如何加密数据的详细信息。 因此,加密模式会影响部分加密算法。

加密模式有时可以与多种不同的加密算法一起使用-就像附加在核心加密算法上的技术一样。 这就是为什么将这些模式与加密算法本身分开,而将其称为加密算法的“附加组件”。 这是一些最著名的密码模式

  • ECB - Electronic Codebook

  • CBC - Cipher Block Chaining

  • CFB - Cipher Feedback

  • OFB - Output Feedback

  • CTR - Counter

实例化密码时,可以将其模式附加到加密算法的名称中。 例如,要使用密码块链接(CBC)创建AES密码实例,请使用以下代码:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

由于密码块链接也需要“填充方案”,因此填充方案会附加在加密算法名称字符串的末尾。

请记住,默认的Java SDK加密提供程序并不支持所有加密算法和模式。 您可能需要安装像Bouncy Castle这样的外部提供程序,才能使用所需的模式和填充方案创建所需的Cipher实例。

初始化Cipher

您必须先对其进行初始化,然后才能使用Cipher实例。 密码的初始化是通过调用其init()方法完成的。 init()方法采用两个参数:

  • Encryption / decryption cipher operation mode.

  • Encryption / decryption key.

这是在加密模式下初始化密码实例的示例:

Key key = ... // get / create symmetric encryption key
cipher.init(Cipher.ENCRYPT_MODE, key);

这是在解密模式下初始化密码实例的示例:

Key key = ... // get / create symmetric encryption key
cipher.init(Cipher.DECRYPT_MODE, key);

加密和解密数据

为了使用Cipher实例加密或解密数据,您可以调用以下两种方法之一:

  • update()

  • doFinal()

update()和doFinal()有多个覆盖的版本,它们具有不同的参数。 我将在这里介绍最常用的版本。

如果必须加密或解密单个数据块,只需对数据调用doFinal()即可进行加密或解密。 这是一个加密示例:

byte[] plainText  = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8");
byte[] cipherText = cipher.doFinal(plainText);

在解密数据的情况下,代码实际上看起来几乎相同。 请记住,密码实例必须初始化为解密模式。 这是解密单个密文块的样子:

byte[] plainText = cipher.doFinal(cipherText);

如果您必须加密或解密多个数据块,例如 一个大文件中有多个块,则对每个数据块调用一次update(),最后对最后一个数据块调用doFinal()。 这是加密多个数据块的示例:

byte[] data1 = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8");
byte[] data2 = "zyxwvutsrqponmlkjihgfedcba".getBytes("UTF-8");
byte[] data3 = "01234567890123456789012345".getBytes("UTF-8");

byte[] cipherText1 = cipher.update(data1);
byte[] cipherText2 = cipher.update(data2);
byte[] cipherText3 = cipher.doFinal(data3);

最后一个数据块需要调用doFinal()的原因是,某些加密算法需要填充数据以适合特定的密码块大小(例如8字节边界)。 但是-我们不想填充加密的中间数据块。 因此,对中间数据块的update()调用,对最后一个数据块的doFinal()调用。

解密多个数据块时,您还可以为中间数据块调用Cipher update()方法,为最后一个块调用doFinal()方法。 这是使用Java Cipher实例解密多个数据块的示例:

byte[] plainText1 = cipher.update(cipherText1);
byte[] plainText2 = cipher.update(cipherText2);
byte[] plainText3 = cipher.doFinal(cipherText3);

同样,必须将Cipher实例初始化为解密模式,此示例才能正常工作。

加密/解密字节数组的一部分

Java Cipher类的加密和解密方法可以对存储在字节数组中的部分数据进行加密或解密。 您只需将偏移量和长度传递给update()和/或doFinal()方法。 这是一个例子:

int offset = 10;
int length = 24;
byte[] cipherText = cipher.doFinal(data, offset, length);

此示例将从具有索引8和24个字节的字节开始加密(或解密,具体取决于密码的初始化)。

加密/解密为现有的字节数组

到目前为止,本教程中显示的所有加密和解密示例都已将加密或解密的数据返回到新的字节数组中。 但是,也可以将数据加密或解密为现有的字节数组。 这对于减少创建的字节数组的数量很有用。

通过将目标字节数组作为参数传递给update()和/或doFinal()方法,可以将数据加密或解密为现有的字节数组。 这是一个例子:

int offset = 10;
int length = 24;
byte[] dest = new byte[1024];
cipher.doFinal(data, offset, length, dest);

本示例将索引为10和24字节的字节中的数据加密,从偏移量0转发到目标字节数组。如果要为目标字节数组设置不同的偏移量,则有update()和doFinal()版本 需要额外的偏移量参数。 这是在dest数组中使用偏移量调用doFinal()方法的示例:

int offset = 10;
int length = 24;
byte[] dest = new byte[1024];
int destOffset = 12
cipher.doFinal(data, offset, length, dest, destOffset);

重用密码实例

初始化Java Cipher实例是一项昂贵的操作。 因此,重用Cipher实例是一个好主意。 幸运的是,Cipher类在设计时考虑了重用。

当您在Cipher实例上调用doFinal()方法时,Cipher实例将返回到初始化后的状态。 然后,可以使用Cipher实例再次加密或解密更多数据。

这是重用Java Cipher实例的示例:

Cipher cipher = Cipher.getInstance("AES");

Key key = ... // get / create symmetric encryption key
cipher.init(Cipher.ENCRYPT_MODE, key);

byte[] data1 = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8");
byte[] data2 = "zyxwvutsrqponmlkjihgfedcba".getBytes("UTF-8");

byte[] cipherText1 = cipher.update(data1);
byte[] cipherText2 = cipher.doFinal(data2);

byte[] data3 = "01234567890123456789012345".getBytes("UTF-8");
byte[] cipherText3 = cipher.doFinal(data3);

首先,创建并初始化Cipher实例,然后将其用于加密两个相干数据块。 注意对这两个数据块的update()然后doFinal()的调用。 现在,可以再次使用Cipher实例来加密更多数据。 这是通过对第三个数据块的doFinal()调用完成的。 调用完doFinal()之后,您可以使用相同的Java Cipher实例加密另一个数据块。

MessageDigest

Java MessageDigest类表示一种加密哈希函数,可以根据二进制数据计算消息摘要。当您收到一些加密的数据时,您将无法从数据本身中看到它是否在运输过程中被修改。消息摘要可以帮助减轻该问题。

为了能够检测到加密数据在传输中是否已被修改,发送者可以从数据中计算出消息摘要,并将其与数据一起发送。收到加密的数据和消息摘要后,您可以从数据中重新计算消息摘要,并检查计算出的消息摘要是否与随数据接收的消息摘要匹配。如果两个消息摘要匹配,则有可能在传输期间未修改加密数据。

要使消息摘要用作修改检测机制,必须满足几个条件。但是,确切的条件是密码学理论的一部分,因此您将必须访问该理论以阅读如何正确使用消息摘要。本教程仅说明如何在MessageDigest类中使用消息摘要的Java密码学API表示形式。

创建一个MessageDigest实例

要创建Java MessageDigest实例,请调用MessageDigest类的静态getInstance()方法。 这是创建MessageDigest实例的示例:

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


传递给getInstance()方法的text参数是要使用的具体消息摘要算法的名称。

消息摘要算法

Java密码学API支持以下消息摘要算法(尽管您的具体密码学提供程序可能支持更多!):

  • MD2

  • MD5

  • SHA-1

  • SHA-256

  • SHA-384

  • SHA-512

并非所有这些消息摘要算法都同样安全。 在撰写本文时,建议您使用SHA-256或更高版本以获得最大程度的安全性。

计算摘要

创建Java MessageDigest实例后,就可以使用它从数据中计算消息摘要。 如果您有单个数据块来计算消息摘要,请使用digest()方法。 这是从单个数据块计算消息摘要的样子:

byte[] data1 = "0123456789".getBytes("UTF-8");

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] digest = messageDigest.digest(data1);

如果您要在同一消息摘要中包含多个数据块,请调用update()方法并结束对digest()的调用。 这是从多个数据块计算消息摘要的样子:

byte[] data1 = "0123456789".getBytes("UTF-8");
byte[] data2 = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(data1);
messageDigest.update(data2);

byte[] digest = messageDigest.digest();

Mac

Java Mac(javax.crypto.Mac类可以从二进制数据创建消息身份验证代码(MAC)。MAC是已用密钥加密的消息摘要。只有拥有密钥后,才能验证MAC 。

创建Mac实例

必须先创建Mac实例,然后才能使用Java Mac类。 使用getInstance()方法创建Mac实例。 这是一个Java Mac实例化示例:

Mac mac = Mac.getInstance("HmacSHA256");

传递给Mac getInstance()方法的String参数包含要使用的MAC算法的名称。 在这种情况下,MAC算法为HmacSHA256。

初始化

创建后,必须初始化Java Mac实例。 您可以通过调用Mac实例的init()方法来初始化Mac实例,该方法将Mac实例要使用的密钥作为参数传递。 这是一个Java Mac初始化示例:

byte[] keyBytes   = new byte[]{0,1,2,3,4,5,6,7,8 ,9,10,11,12,13,14,15};
String algorithm  = "RawBytes";
SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm);

mac.init(key);

Mac的init()方法采用一个Key实例。 在此示例中,使用SecretKeySpec来实现Key接口。

计算Mac

初始化Java Mac实例后,您可以开始使用它计算MAC值。 要计算MAC值,请调用Mac update()或doFinal()方法。 如果只有一个数据块可为其计算MAC,则可以直接调用doFinal(),如下所示:

byte[] data  = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
byte[] macBytes = mac.doFinal(data);

如果您有多个数据块来计算其MAC,例如 如果要逐块读取文件,则必须在每个块中调用update()方法,并以对doFinal()的调用结束。 这是一个例子:

byte[] data  = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
byte[] data2 = "0123456789".getBytes("UTF-8");

mac.update(data);
mac.update(data2);

byte[] macBytes = mac.doFinal();

Signature

Java Signature类(java.security.Signature)可以为二进制数据创建数字签名。 数字签名是使用私钥/公钥对的私钥加密的消息摘要。 拥有公钥的任何人都可以验证数字签名。

创建实例

必须先创建一个Signature实例,然后才能使用Java Signature类。 您可以通过调用静态getInstance()方法来创建一个Signature实例。 这是一个创建Java签名实例的示例:

Signature signature = Signature.getInstance("SHA256WithDSA");

作为参数传递给getInstance()方法的String是要使用的数字签名算法的名称。

初始化

创建Java签名实例后,需要先对其进行初始化,然后才能使用它。 您可以通过调用签名实例的init()方法来初始化它。 这是一个Java签名初始化示例:

SecureRandom secureRandom = new SecureRandom();
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();

signature.initSign(keyPair.getPrivate(), secureRandom);

如您所见,Signature实例使用私钥/公钥对的私钥和SecureRandom实例进行初始化。

创建数字签名

签名实例初始化后,您可以使用它来创建数字签名。 您可以通过多次调用update()方法来创建数字签名,最后再调用sign()。 这是为二进制数据块创建数字签名的示例:


Signature signature = Signature.getInstance("SHA256WithDSA");

signature.initVerify(keyPair.getPublic());

请注意,现在如何将Java Signature实例初始化为验证模式,并将公钥/私钥对中的公钥作为参数传递。

初始化为验证模式后,您可以使用Signature实例来验证数字签名。 这是验证数字签名的样子:

byte[] data2 = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
signature2.update(data2);

boolean verified = signature2.verify(digitalSignature);

KeyPair

Java KeyPair类(java.security.KeyPair表示非对称密钥对。换句话说,是公钥+私钥对。执行非对称加密(例如,加密或签名数据)时通常使用KeyPair实例。

获取KeyPair实例

通常,您将从Java密钥库或Java KeyPairGenerator获得KeyPair实例。

访问密钥对公共密钥

您可以通过调用KeyPair的getPublic()方法来访问它的PublicKey。 她是一个从KeyPair实例获取PublicKey的示例:

PublicKey publicKey = keyPair.getPublic();

访问KeyPair私钥

您可以通过调用get Private()方法来访问密钥对的私钥。 这是从KeyPair实例获取PrivateKey的示例:

PrivateKey privateKey = keyPair.getPrivate();

KeyGenerator

Java KeyGenerator类(javax.crypto.KeyGenerator)用于生成对称加密密钥。 对称加密密钥是通过对称加密算法用于数据加密和解密的密钥。 在此Java KeyGenerator教程中,我将向您展示如何生成对称加密密钥。

创建实例

必须先创建KeyGenerator实例,然后才能使用Java KeyGenerator类。 您可以通过调用静态方法getInstance()来创建KeyGenerator实例,该方法将要为其创建密钥的加密算法的名称作为参数传递。 这是创建Java KeyGenerator实例的示例:

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

本示例创建一个KeyGenerator实例,该实例可以为AES加密算法生成密钥。

初始化

创建KeyGenerator实例后,必须对其进行初始化。 初始化KeyGenerator实例是通过调用其init()方法来完成的。 这是初始化KeyGenerator实例的示例:

SecureRandom secureRandom = new SecureRandom();
int keyBitSize = 256;

keyGenerator.init(keyBitSize, secureRandom);

KeyGenerator init()方法采用两个参数:要生成的密钥的位大小,以及在密钥生成期间使用的SecureRandom。

生成密钥

Java KeyGenerator实例初始化后,就可以使用它来生成密钥。 生成密钥是通过调用KeyGenerator generateKey()方法来完成的。 这是生成对称密钥的示例:

SecretKey secretKey = keyGenerator.generateKey();

KeyPairGenerator

Java KeyPairGenerator类(java.security.KeyPairGenerator)用于生成非对称加密/解密密钥对。 非对称密钥对由两个密钥组成。 第一密钥通常用于加密数据。 第二密钥,用于解密用第一密钥加密的数据。

公钥,私钥类型密钥对

最常见的非对称密钥对类型是密钥对的公钥和私钥类型。 私钥用于加密数据,公钥可以再次用于解密数据。 实际上,您还可以使用公钥加密数据,并使用私钥解密数据。

私钥通常被保密,而公钥则可以公开使用。 因此,如果杰克用他的私钥加密某些数据,那么拥有杰克公钥的每个人都可以解密它。

创建一个KeyPairGenerator实例

要使用Java KeyPairGenerator,必须首先创建一个KeyPairGenerator实例。 通过调用方法getInstance()方法来创建KeyPairGenerator实例。 这是创建Java KeyPairGenerator实例的示例:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");

getInstance()方法采用加密算法的名称来为其生成密钥对。 在此示例中,我们使用名称RSA。

初始化KeyPairGenerator

根据生成密钥对的算法的不同,您可能必须初始化KeyPairGenerator实例。 初始化KeyPairGenerator的方法是调用其initialize()方法。 这是初始化Java KeyPairGenerator实例的示例:

keyPairGenerator.initialize(2048);

本示例初始化KeyPairGenerator以生成2048位大小的密钥。

生成密钥对

要使用KeyPairGenerator生成KeyPair,请调用generateKeyPair()方法。 这是使用KeyPairGenerator生成KeyPair的示例:

KeyPair keyPair = keyPairGenerator.generateKeyPair();

KeyStore

Java KeyStore是可以包含密钥的数据库。 Java KeyStore由KeyStore(java.security.KeyStore)类表示。可以将KeyStore写入磁盘并再次读取。整个密钥库都可以用密码保护,并且密钥库中的每个键条目都可以用自己的密码保护。这使KeyStore类成为安全处理加密密钥的有用机制。

密钥库可以保存以下类型的密钥:

  • 私钥

  • 公钥+证书

  • 秘钥

私钥和公钥用于非对称加密。公钥可以具有关联的证书。证书是一种文件,用于验证声称拥有公钥的个人,组织或设备的身份。证书通常由验证方进行数字签名以作为证明。

秘密密钥用于对称加密。在许多情况下,建立安全连接后会协商对称密钥。因此,与秘密密钥相比,您将更经常地将公共密钥和私有密钥存储在KeyStore中。

创建密钥库

您可以通过调用Java KeyStore实例的getInstance()方法来创建它。这是创建KeyStore实例的示例:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());


本示例创建Java默认类型的KeyStore实例。 也可以通过将不同的参数传递给getInstance()方法来创建其他类型的KeyStore实例。 例如,下面是创建PKCS12类型的KeyStore的示例:

KeyStore keyStore = KeyStore.getInstance("PKCS12");

加载密钥库
必须先加载KeyStore实例,然后才能使用它。 通常将KeyStore实例写入磁盘或其他类型的存储中,以备后用。 这就是为什么KeyStore类假定您必须先读取其数据,然后才能使用它。 但是,可以初始化一个没有数据的空KeyStore实例,这将在以后看到。

通过调用KeyStore load()方法可以从文件或其他存储中加载KeyStore数据。 load()有两个参数:

一个从其加载KeyStore数据的InputStream。
一个包含KeyStore密码的char [](char数组)。

这是加载Java KeyStore的示例:


char[] keyStorePassword = "123abc".toCharArray();
try(InputStream keyStoreData = new FileInputStream("keystore.ks")){
    keyStore.load(keyStoreData, keyStorePassword);
}

本示例加载位于keystore.ks文件中的KeyStore文件。

如果您不想将任何数据加载到KeyStore中,只需为InputStream参数传递null。 这是加载空KeyStore的样子:

keyStore3.load(null, keyStorePassword);

您必须始终使用数据或null加载KeyStore实例。 否则,KeyStore将未初始化,并且对其方法的所有调用都将引发异常。

获取密匙

您可以通过Java KeyStore实例的getEntry()方法获取其键。 KeyStore条目映射到标识密钥的别名,并由密钥密码保护。 因此,要访问密钥,必须将密钥别名和密码传递给getEntry()方法。 这是访问KeyStore实例中的键条目的示例:

char[] keyPassword = "789xyz".toCharArray();
KeyStore.ProtectionParameter entryPassword =
        new KeyStore.PasswordProtection(keyPassword);

KeyStore.Entry keyEntry = keyStore3.getEntry("keyAlias", entryPassword);

如果知道要访问的密钥条目是私钥,则可以将KeyStore.Entry实例强制转换为KeyStore.PrivateKeyEntry。 看起来是这样的:

KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)
        keyStore3.getEntry("keyAlias", entryPassword);

强制转换为KeyStore.PrivateKeyEntry之后,您可以通过以下方法访问私钥,证书和证书链:

  • getPrivateKey()

  • getCertificate()

  • getCertificateChain()

设置密钥

您还可以将密钥设置为KeyStore实例。 这是在密钥库实例中设置秘密密钥(对称密钥)的示例:

SecretKey secretKey = getSecretKey();
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);

keyStore3.setEntry("keyAlias2", secretKeyEntry, entryPassword);

存储 KeyStore

有时您可能希望将KeyStore存储到某个存储(磁盘,数据库等),以便下次可以再次加载它。 您可以通过调用store()方法来存储KeyStore。 这是存储密钥库的示例

char[] keyStorePassword = "123abc".toCharArray();
try (FileOutputStream keyStoreOutputStream = new FileOutputStream("data/keystore.ks")) {
    keyStore3.store(keyStoreOutputStream, keyStorePassword);
}

Keytool

Java Keytool是一种命令行工具,可以生成公用密钥/专用密钥对并将其存储在Java KeyStore中。 Keytool可执行文件随Java SDK(或JRE)一起分发,因此,如果安装了SDK,则还将具有Keytool可执行文件。

Keytool可执行文件称为keytool。 要执行它,请打开命令行(cmd,控制台,shell等)。 并将目录更改为Java SDK安装的bin目录。 键入keytool,然后按Enter键。 您应该看到类似以下内容:

C:\Program Files\Java\jdk1.8.0_111\bin>keytool
Key and Certificate Management Tool

Commands:

 -certreq            Generates a certificate request
 -changealias        Changes an entry's alias
 -delete             Deletes an entry
 -exportcert         Exports certificate
 -genkeypair         Generates a key pair
 -genseckey          Generates a secret key
 -gencert            Generates certificate from a certificate request
 -importcert         Imports a certificate or a certificate chain
 -importpass         Imports a password
 -importkeystore     Imports one or all entries from another keystore
 -keypasswd          Changes the key password of an entry
 -list               Lists entries in a keystore
 -printcert          Prints the content of a certificate
 -printcertreq       Prints the content of a certificate request
 -printcrl           Prints the content of a CRL file
 -storepasswd        Changes the store password of a keystore

Use "keytool -command_name -help" for usage of command_name

C:\Program Files\Java\jdk1.8.0_111\bin>

Keytool 脚本

Keytool命令带有很多参数,可能很难记住正确设置它们。 因此,最好在其中包含Keytool命令的情况下创建一些Keytool CMD或Shell脚本。这些脚本使以后重新执行keytool命令更容易,并且可以稍后再查看如何生成KeyStore。 。

生成密钥对

生成公钥/私钥对是使用Java Keytool的最常见任务之一。 生成的密钥对作为自签名密钥对插入到Java KeyStore文件中。 这是使用Keytool生成密钥对的常规命令行格式:

-genkeypair
    -alias alias
    -keyalg keyalg
    -keysize keysize
    -sigalg sigalg
    -dname dname
    -keypass keypass
    -validity valDays
    -storetype storetype
    -keystore keystore
    -storepass storepass
    -providerClass provider_class_name
    -providerArg provider_arg
    -v
    -protected
    -Jjavaoption

参数在“ Keytool参数”部分中进行了说明。 并非所有这些论点都是必需的。 许多是可选的。 Keytool会告诉您是否缺少必需的参数。

换行符不应包含在最终命令中。 换行仅是为了使此处的命令格式更易于阅读。

这是一个示例keytool -genkeypair命令。 请记住在尝试之前删除换行符!

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool" -genkeypair
    -alias testkey
    -keyalg RSA
    -keysize 2048
    -dname "CN=Jakob Jenkov, OU=Jenkov Aps, O=Jenkov Aps, L=Copenhagen, ST=Unknown, C=DK"
    -keypass 123456
    -validity 100
    -storetype JKS
    -keystore keystore.jks
    -storepass abcdef

导出证书

Java Keytool也可以导出存储在KeyStore中的证书。 这是Keytool命令查找导出证书的方式:


-exportcert
    -alias alias
    -file cert_file
    -storetype storetype
    -keystore keystore
    -storepass storepass
    -providerName provider_name
    -providerClass provider_class_name
    -providerArg provider_arg
    -rfc
    -v
    -protected
    -Jjavaoption

参数在“ Keytool参数”部分中进行了说明。 并非所有这些论点都是必需的。 许多是可选的。 Keytool会告诉您是否缺少必需的参数。

这是一个Keytool命令示例,该示例导出密钥对的证书。 在命令行上输入命令时,切记要删除换行符。


"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"
    -exportcert
    -alias testkey
    -keypass 123456
    -storetype JKS
    -keystore keystore.jks
    -file cert.cert
    -rfc
    -storepass abcdef

导入证书

Java Keytool也可以将证书导入KeyStore。 这是Keytool命令查找导入证书的方式:

-importcert
    -alias alias
    -file cert_file
    -keypass keypass
    -noprompt
    -trustcacerts
    -storetype storetype
    -keystore keystore
    -storepass storepass
    -providerName provider_name
    -providerClass provider_class_name
    -providerArg provider_arg
    -v
    -protected
    -Jjavaoption

参数在“ Keytool参数”部分中进行了说明。 并非所有这些论点都是必需的。 许多是可选的。 Keytool会告诉您是否缺少必需的参数。

这是一个示例Keytool命令,该命令将证书导入KeyStore。 在命令行上输入命令时,切记删除换行符

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"
    -importcert
    -alias testkey
    -keypass 123456
    -storetype JKS
    -keystore keystore2.jks
    -file cert.cert
    -rfc
    -storepass abcdef

列出密钥库条目

要列出Java KeyStore中的条目,可以使用Keytool -list命令。 这是Keytool -list命令的格式。 换行仅是为了使命令格式更易于阅读。 运行命令之前,请删除换行符。

-list
    -alias alias
    -storetype storetype
    -keystore keystore
    -storepass storepass
    -providerName provider_name
    -providerClass provider_class_name
    -providerArg provider_arg
    -v
    -rfc
    -protected
    -Jjavaoption

参数在“ Keytool参数”部分中进行了说明。 并非所有这些论点都是必需的。 许多是可选的。 Keytool会告诉您是否缺少必需的参数。

这是一个Keytool -list命令示例。 记住要删除换行符!

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"
    -list
    -storetype JKS
    -keystore keystore.jks
    -storepass abcdef


此Keytool -list命令将列出给定KeyStore中的所有条目。 运行此Keytool -list命令的输出将类似于以下内容:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

testkey, 19-Dec-2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): 4F:4C:E2:C5:DA:36:E6:A9:93:6F:10:36:9E:E5:E8:5A:6E:F2:11:16

如果在Keytool -list命令中包括-alias参数,则仅列出与给定别名匹配的条目。 这是带有-alias参数的示例Keytool -list命令:

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"
    -list
    -alias testkey
    -storetype JKS
    -keystore keystore.jks
    -storepass abcdef

运行上述Keytool -list命令的输出将类似于以下内容:

y -storetype JKS -keystore keystore.jks -storepass abcdef
testkey, 15-Dec-2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): 71:B0:6E:F1:E9:5A:E7:F5:5E:78:71:DC:08:80:47:E9:5F:F8:6D:25

删除密钥库条目

Keytool具有一个可以删除Java KeyStore中的键条目的命令。 用于删除密钥的Keytool命令为-delete。 这是Keytool -delete命令的格式:

-delete
    -alias alias
    -storetype storetype
    -keystore keystore
    -storepass storepass
    -providerName provider_name
    -providerClass provider_class_name
    -providerArg provider_arg
    -v
    -protected
    -Jjavaoption


参数在“ Keytool参数”部分中进行了说明。 并非所有这些论点都是必需的。 许多是可选的。 Keytool会告诉您是否缺少必需的参数。

这是Keytool -delete命令示例。 记住在运行前删除换行符!

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"
    -delete
    -alias testkey
    -storetype JKS
    -keystore keystore.jks
    -storepass abcdef

此Keytool -delete命令将从存储在文件keystore.jks中的KeyStore中删除带有别名testkey的KeyStore条目。

生成证书申请

Java Keytool可以使用-certreq命令生成证书请求。 证书请求是对证书颁发机构(CA)为您的组织创建公共证书的请求。 证书请求生成后,应将其发送到您要为其创建证书的CA(例如Verisign,Thawte或其他CA)。

在为私钥,公钥对生成证书请求之前,您必须已将该私钥,公钥对生成到密钥库中(或将其导入)。

这是用于生成证书请求的命令格式。 试用此命令时,请记住删除所有换行符

-certreq
    -alias alias
    -sigalg sigalg
    -file certreq_file
    -keypass keypass
    -storetype storetype
    -keystore keystore
    -storepass storepass
    -providerName provider_name
    -providerClass provider_class_name
      -providerArg provider_arg
    -v
    -protected
    -Jjavaoption

参数在“ Keytool参数”部分中进行了说明。 并非所有这些论点都是必需的。 许多是可选的。 Keytool会告诉您是否缺少必需的参数。

这是一个Java Keytool -certreq命令示例:

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"
    -certreq
    -alias testkey
    -keypass 123456
    -storetype JKS
    -keystore keystore.jks
    -storepass abcdef
    -file certreq.certreq

此命令将为以别名testkey存储在密钥库文件keystore.jks中的密钥生成证书请求,并将证书请求写入名为certreq.certreq的文件中。

请记住,仅包含换行符以使命令更易于阅读。 自己在命令行上键入命令时忽略它们

Certificate

Java证书类(java.security.cert.Certificate)表示密码身份证书。 Java证书类实例包含名称以及它标识的实体的其他详细信息,还可能包含来自证书颁发机构(CA)的数字签名。

Java Certificate类是一个抽象类,因此尽管您可以将Certificate用作变量类型,但您的变量将始终指向Certificate的子类。

Java证书类具有一个子类-X509Certificate类。 此类表示X.509证书,该证书在HTTPS和TLS中用作身份证书。

获取证书实例

您可以通过以下方式获取证书实例:

  • From a CertificateFactory.

  • From a KeyStore.

getEncoded()

Java证书的getEncoded()方法以字节数组形式返回证书的编码版本。 例如,如果证书是X509Certificate,则返回的字节数组将包含证书实例的X.590(ASN.1 DER)编码版本。 这是一个getEncoded()示例:

byte[] encodedCertificate = certificate.getEncoded();

getPublicKey()

Java Certificate getPublicKey()方法返回此Certificate实例的PublicKey。 这是一个getPublicKey()示例:

PublicKey certificatePublicKey = certificate.getPublicKey();

getType()

Java Certificate getType()方法返回Certificate实例的类型。 这是一个getType()示例:

String certificateType = certificate.getType();

verify()

Java证书类包含三个verify()方法。 这些方法可用于验证证书是否已使用与预期公钥匹配的私钥进行了真正的签名。 这是一个Java证书verify()示例:

// get expected public key from somewhere else (not Certificate instance !!)
PublicKey expectedPublicKey = ... ;

try{
    certificate.verify(expectedPublicKey);

} catch (InvalidKeyException e) {
    // certificate was not signed with given public key

} catch (NoSuchAlgorithmException |
         NoSuchProviderException |
         SignatureException |
         CertificateException e){
    // something else went wrong
}


verify()方法返回void。 如果验证失败,则将引发InvalidKeyException。 如果未抛出异常,则可以将Certificate实例视为已验证。

CertificateFactory

Java CertificateFactory类(java.security.cert.CertificateFactory)能够从X.509(ASN.1 DER)之类的二进制证书编码创建Java证书实例。

Java CertificateFactory也可以创建CertPath实例。 CertPath是证书链,其中链中的每个证书由链中的下一个证书签名。 有关CertPath类的更多信息,请参见Java CertPath教程。

创建一个CertificateFactory实例

在创建证书实例之前,必须创建一个Java CertificateFactory实例。 这是创建CertificateFactory的示例:

 CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");


本示例创建一个CertificateFactory实例,该实例能够创建X.509证书实例(X509Certificate-Certificate的子类)。

创建证书实例

创建CertificateFactory实例后,即可开始创建Certificate实例。 您可以通过generateCertificate()方法进行操作。 这是一个generateCertificate()示例:


InputStream certificateInputStream = new FileInputStream("my-x509-certificate.crt");

Certificate certificate = certificateFactory.generateCertificate(certificateInputStream);


创建一个CertPath实例

Java CertificateFactory也可以创建一个CertPath实例。 您可以通过调用CertificateFactory generateCertPath()方法来创建一个CertPath实例。 这是一个generateCertPath()示例:


InputStream certificateInputStream = new FileInputStream("my-x509-certificate-chain.crt");



CertPath certPath = certificateFactory.generateCertPath(certificateInputStream);

参考文章

http://tutorials.jenkov.com/java-cryptography/index.html

创建Java keystore文件的完整指南 在信息安全的世界中,秘密键,通常被称为私钥,是密码学中用于保持数据机密性和验证身份的关键。私钥是不对称加密系统的一部分,与之对应的是公钥。私钥必须保持机密,因为它可以解密由对应公钥加密的信息,以及用于数字签名的验证过程。 阅读详情

相关推荐

Windows升级保留个人文件和应用灰色?改注册表版本指纹

Windows 升级安装并非简单跳过下一步,安装程序会先读取注册表中 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion 下的 EditionID、ProductName、CompositionEditionID 等版本指纹,与目标镜像 install.wim/esd 记录的版本类型做双向匹配。若当前系统被识别为 LTSC、精简版或跨版本降级,兼容性扫描会判定升级路径不可用,于是“保留个人文件和应用”变灰,只能全新安装。理解版本指纹与升级可行性表的匹配机制,可

weixin_31986143的博客 363

java中cipher什么意思,cipher.update在Java中做什么?

I am implementing DES - CBC. I am confused as to what cipher.init, cipher.update and cipher.dofinal do. I just use init to set the key and dofinal to get the result. I don't use update. Is that corre...

weixin_39808953的博客 642

2 利用ITK实现多帧Dicom读取,VTK实现数据显示

vtk中也有dicom读写类,但是只能完成单帧DICOM数据读取,这对于实际应用是非常不利的。而ITK可以实现dicom多帧读取,通常情况ITK与VTK也会结合使用(ITK处理,VTK显示),所以就一起学习下吧!

buerbuhuitou的博客 1564

基于Cipher的Java加密工具类

基于Cipher的Java加密工具类,可用作登录,简单的数据加密。

2301_77523019的博客 1552

Android应用隐私合规自动化检测:Frida与Camille实战指南

在移动应用安全与隐私合规领域,动态代码插桩技术已成为核心检测手段。其原理是通过运行时注入,实时监控和修改应用行为,从而绕过传统静态分析的局限。这项技术的核心价值在于能够精准捕获应用在运行时的敏感数据调用与网络传输行为,为隐私合规审计、安全测试提供直接证据。在实际应用场景中,它尤其适用于自动化检测违规收集个人信息、追踪数据流向等任务。本文聚焦于利用Frida这一动态插桩框架,结合Camille隐私合规检测工具集,构建自动化监控环境。通过注入JavaScript代码,实现对Android敏感API(如获取设备标

weixin_34254464的博客 388

k8s 100个高频面试题

以下是 100 个 Kubernetes(k8s)高频面试题及其答案,涵盖了 Kubernetes 的核心概念、架构、组件、工作原理以及实际应用。答案:Master 节点组件:API Server:提供 RESTful API 接口,用于与集群交互。etcd:分布式键值存储,用于存储集群的配置数据和状态信息。Controller Manager:运行各种控制器进程,负责维护集群的状态。Scheduler:负责将 Pod 调度到合适的节点上运行。Worker 节点组件:Kubelet:运行在每个节点上的代理,

wankll的专栏 2774

算法加密

package org.jeecgframework.core.util; import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFact

秋风伴落叶 592

西门子1500 PLC与巴鲁夫RFID实战:从硬件接线到数据读写的完整流程

本文详细介绍了西门子S7-1500 PLC与巴鲁夫RFID系统集成的完整实战流程。内容涵盖从硬件选型、接线、PROFINET网络配置,到在TIA Portal中安装GSD文件、组态设备、分配地址,再到使用标准功能块(如FB31)进行程序架构设计、实现数据读写以及错误诊断。文章重点分享了硬件连接要点、软件配置步骤、数据块管理技巧以及调试中常见问题的解决方案,为工业自动化工程师实施RFID项目提供了清晰的指导。

weixin_29161785的博客 385

【Java可执行命令】(十一)Java 密钥库和证书管理工具keytool:玩转密钥库和证书管理,深入解析keytool工具的应用与技巧~

Java的keytool命令是一个强大而灵活的工具,用于生成、导入、导出和管理密钥对和数字证书。它为Java开发人员提供了一种安全可靠的方式来保护应用程序和数据资源。通过遵循合适的使用和操作方法,可以确保密钥和证书的安全性和完整性。有充分的理解和掌握keytool命令,可以更好地进行加密、身份验证和数据保护,并在安全意识和实践中取得成功。

Technology changes the world of life 1万+

【HSCNN解析】HSCNN:从欠采样光谱图重建高光谱图的CNN网络

本文介绍HSCNN,是一个将欠采样光谱图重建为高光谱图的纯CNN网络,2017年提出。

上个大学哪有不疯的?硬撑罢了! 1619

模拟一个基站和一个移动台之间的信号传播

同样使用时间序列和上述参数计算出反射径信号的信号强度。根据时间序列和上述参数,计算出直射径信号的信号强度。该信号被视为一个简单的正弦波信号,其频率是2Hz。:时间序列,从0.1秒开始,每隔0.0001秒采样一次,直到12秒。:设置坐标轴范围,横轴范围为0到12秒,纵轴范围为-0.5到0.5。:移动台移动的速度。:移动台距离基站的初始距离。:基站到反射墙的距离。假设基站到反射墙的距离为15米。:绘制直射径信号、反射径信号和合成信号的波形图。:添加标签,标注每条曲线对应的含义。表示反射径信号的颜色为绿色,

Fanjufei的博客 290

Java KeyStore 文件生成

java keystore文件生成 ...

u011196623的专栏 2919

内存泄漏系列专题分析之二十三:meminfo无法统计到的黑洞内存泄漏分析

内存泄漏系列专题分析之二十三:meminfo无法统计到的黑洞内存泄漏分析

683

jenkov.tutorials系列(Java加密与解密概览)

jenkov.tutorials系列(Java加密与解密概览) Java密码学扩展 Java加密API由正式称为Java加密扩展的Java提供。 Java密码学扩展有时也通过缩写JCE来引用。 Java密码体系结构 Java密码学体系结构(JCA)是Java密码学API内部设计的名称。 JCA是围绕一些中央通用类和接口构建的。 这些接口背后的实际功能由提供程序提供。 因此,您可以使用Cipher类...

Coder_py的博客 491

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Java中的KeyStore和TrustStore以及 keytool 命令的使用

当应用需要使用SSL/TLS进行通信时,我们将会使用到密钥库(keystore)和信任库(truststore)。 在 JDK8 之前,这些文件的默认格式为 JKS;从 JDK9 开始,默认格式为PKCS12。KeyStore 存储一个私钥和一个相关的证书,或者相关的证书链(由客户证书和一个或多个证书颁发机构(CA)证书组成)。存储时,使用别名存储。它通常用于表明通信一方的身份。比如服务器使用 HTTPS,在 SSL 握手期间,服务器从密钥库中查找私钥,并将其对应的公钥和证书提供给客户端。一般都是单向认证,

qq_31856061的博客 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java.security包中的KeyStore类详解

KeyStore是一个抽象概念上的密钥存储库,允许应用程序以安全的方式存储和管理各种形式的密钥与证书对。: 返回提供此KeyStore实例的提供者的名称。: 根据指定类型和提供者获取KeyStore实例。: 根据指定类型(默认使用系统默认的安全服务提供者)获取KeyStore实例。: 获取默认的密钥库类型。: 返回此KeyStore的安全服务提供者对象。getType(): 返回此KeyStore的类型。: 根据别名获取密钥。: 获取给定别名的证书链。: 获取给定别名的证书。

一起coding,一起嗨。 2929

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java keystore如何使用_java KeyStore 使用

public class KeyStoreextends Object此类表示密钥和证书的存储设施。KeyStore管理不同类型的条目。每种类型的条目都实现KeyStore.Entry接口。提供了三种基本的KeyStore.Entry实现:KeyStore.PrivateKeyEntry此类型的条目保存一个加密的PrivateKey,可以选择用受保护格式存储该私钥,以防止未授权访问。它还随附一个相...

weixin_28314575的博客 5433

自建keystore 再下载网页证书,导入自建keystore,最后用此keystore 读取https网页(java读取https的4种方法和详细认证网页证书)

java

m0_59802969的博客 4992

Java keytool keystore的相关概念介绍与使用

⏹Java keytool keystore的相关概念介绍与使用

菜鸟记录 2393

Jenkov写的Java并发编程和多线程教程

练练英语,翻译自http://tutorials.jenkov.com/ JDK 中IO 流部分的作者:jenkov的个人网站 Java 并发编程是一个囊括了多线程、并发、并行(parallelism)的一个java 平台项目。他包括了Java 并发工具,问题,和解决方案。这个Java 并发教程包括了多线程的主要概念,包括关于Java中多线程的并发结构,并发问题,消耗,优点。 Java 并发编程视频教程 如果你更喜欢视频,我录制了一个包括这个教程同样题目的一些视频。你可以在youtube找...

Marain123的博客 532

Java安全——密钥管理

java中的密钥管理和安全概念

多头注意力探索Now 3618

证书格式

REF:http://zxjgoodboy.blog.sohu.com/71003540.html cer后缀的证书文件有两种编码-->DER二进制编码或者BASE64编码(也就是.pem)p7b一般是证书链,里面包括1到多个证书pfx是指以pkcs#12格式存储的证书和相应私钥。在Security编程中,有几种典型的密码交换信息文件格式:DER-encoded certifica

tsimgsong 8010

KeyStore 简述

涉及 Java KeyStore.

O_o 5384

Java密匙库(keystore)的基础知识

一、keystore是什么 keystore是java的密钥库,用来进行通信加密用的,比如数字签名;还有用来保存密钥对的,比如公钥和私钥。一般多用作银行接口相关,保证通讯安全。keystore一般格式为json格式,类似如下: 二、利用keystore签名      ...

m0_38018775的博客 3693

JAVA keystore

java签名/证书机制 java签名/证书机制,可以保障使用者,安全地调用外部提供的jar,防止你信任的jar被篡改。 首先,java的签名,必须是基于jar包的。也就是说,你必须将你要提供的class,打包到jar里。 然后,通过 java 提供的签名工具(jarsigner)对jar包进行签名,发布。 签名原理: 使用非对称算法,生成一对公钥/私钥。   证书 证书是在签名基础

talent210的专栏 6697

JKS(Java KeyStore)是Java平台上用于存储和管理密钥和证书的专用文件格式

JKS文件可以用于多种安全协议中,例如SSL/TLS,以实现安全的数据传输。在Java应用开发中,开发者可以通过Java的安全API来操作JKS文件,包括导入、导出、读取和写入密钥及证书等操作。创建和导入证书到JKS文件中,通常需要使用Java的keytool命令行工具。更改Java KeyStore (JKS) 文件中的密码通常涉及两个步骤:首先,使用当前密码打开JKS文件,然后使用新密码重新保存该文件。请注意,在执行这些操作时,请确保您有权限访问和修改JKS文件,并且知道当前的密钥库密码。

[Blog][Domain] programb.blog.youkuaiyun.com 1546
上一篇: jenkov.tutorials系列(Java加密与解密概览)
下一篇: 剖析LengthFieldBasedFrameDecoder
Coder_py
博客等级 码龄10年 106粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值