Java的Cryptography
Java Cryptography - Introduction
密码学是制作能够提供信息安全的密码系统的艺术和科学。
密码学处理数字数据的实际保护。 它指的是基于提供基本信息安全服务的数学算法的机制设计。 您可以将密码学视为在安全应用程序中包含不同技术的大型工具包的建立。
什么是密码分析?
打破密文的艺术和科学被称为密码分析。
密码分析是密码学的姐妹分支,它们共存。 加密过程产生用于传输或存储的密文。 它涉及密码机制的研究,旨在打破它们。 在设计新的加密技术时也使用密码分析来测试它们的安全性。
密码学原语
密码学原语只不过是密码学中可以有选择地用于提供一组所需安全服务的工具和技术 -
- Encryption
- 散列函数
- 消息验证码(MAC)
- 数字签名
Java中的密码学
Java密码体系结构(JCA)是一组API,用于实现现代密码术的概念,如数字签名,消息摘要,证书,加密,密钥生成和管理,以及安全随机数生成等。
使用JCA开发人员可以构建集成安全性的应用程序。
要在应用程序中集成安全性而不是依赖于复杂的安全算法,您可以轻松调用JCA中提供的相应API以获取所需的服务。
Java Cryptography - Message Digest
散列函数非常有用,几乎出现在所有信息安全应用程序中。
哈希函数是将数字输入值转换为另一个压缩数值的数学函数。 散列函数的输入具有任意长度,但输出始终具有固定长度。
散列函数返回的值称为message digest或简称hash values 。 下图说明了散列函数。
Java提供了一个名为MessageDigest的类,它属于java.security包。 此类支持诸如SHA-1,SHA 256,MD5算法之类的算法,以将任意长度的消息转换为消息摘要。
要将给定邮件转换为邮件摘要,请按照以下步骤进行操作 -
第1步:创建MessageDigest对象
MessageDigest类提供了一个名为**getInstance()**的方法。 此方法接受String变量,该变量指定要使用的算法的名称,并返回实现指定算法的MessageDigest对象。
使用**getInstance()**方法创建MessageDigest对象,如下所示。
1 |
|
第2步:将数据传递给创建的MessageDigest对象
创建消息摘要对象后,需要将消息/数据传递给它。 您可以使用MessageDigest类的**update()**方法执行此操作,此方法接受表示消息的字节数组,并将其添加/传递给上面创建的MessageDigest对象。
1 |
|
第3步:生成消息摘要
您可以使用**digest()**方法生成消息摘要,MessageDigest类此方法计算当前对象的散列函数,并以字节数组的形式返回消息摘要。
使用摘要方法生成消息摘要。
1 |
|
例子 (Example)
以下是从文件中读取数据并生成消息摘要并打印出来的示例。
1 |
|
Java Cryptography - Creating a MAC
MAC( M essage A uessntication C ode)算法是一种对称密钥加密技术,用于提供消息认证。 为了建立MAC过程,发送方和接收方共享对称密钥K.
实质上,MAC是在基础消息上生成的加密校验和,它与消息一起发送以确保消息验证。
使用MAC进行身份验证的过程如下图所示 -
在Java中, javax.crypto包的Mac类提供了消息认证代码的功能。 按照以下步骤使用此类创建消息身份验证代码。
第1步:创建KeyGenerator对象
KeyGenerator类提供getInstance()方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyGenerator对象。
使用getInstance()方法创建KeyGenerator对象,如下所示。
1 |
|
第2步:创建SecureRandom对象
java.Security包的SecureRandom类提供了一个强大的随机数生成器,用于在Java中生成随机数。 实例化此类,如下所示。
1 |
|
第3步:初始化KeyGenerator
KeyGenerator类提供了一个名为init()方法,此方法接受SecureRandom对象并初始化当前的KeyGenerator 。
使用此方法初始化在上一步中创建的KeyGenerator对象。
1 |
|
第4步:生成密钥
使用KeyGenerator类的**generateKey()**方法生成密钥,如下所示。
1 |
|
第5步:初始化Mac对象
Mac类的**init()**方法接受Key对象并使用给定的键初始化当前的Mac对象。
1 |
|
第6步:完成mac操作
Mac类的**doFinal()**方法用于完成Mac操作。 将所需的数据以字节数组的形式传递给此方法,并完成操作,如下所示。
1 |
|
例子 (Example)
以下示例演示如何使用JCA生成消息验证代码(MAC)。 在这里,我们收到一条简单的消息“你好,你好”,并为该消息生成一个Mac。
1 |
|
Java Cryptography - Keys
密码系统是加密技术及其附带基础设施的实现,以提供信息安全服务。 密码系统也称为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的加密过程称为非对称密钥加密。 尽管密钥是不同的,但它们在数学上是相关的,因此通过解密密文来检索明文是可行的。
Java Cryptography - Storing keys
使用/生成的密钥和证书存储在称为密钥库的数据库中。 默认情况下,此数据库存储在名为**.keystore**的文件中。
您可以使用java.security包的KeyStore类访问此数据库的内容。 它管理三个不同的条目,即PrivateKeyEntry,SecretKeyEntry,TrustedCertificateEntry。
- PrivateKeyEntry
- SecretKeyEntry
- TrustedCertificateEntry
在密钥库中存储密钥
在本节中,我们将学习如何在密钥库中存储密钥。 要在密钥库中存储密钥,请按照以下步骤操作。
第1步:创建KeyStore对象
java.security包的KeyStore类的**getInstance()**方法接受表示密钥库类型的字符串值,并返回KeyStore对象。
使用**getInstance()**方法创建KeyStore类的对象,如下所示。
1 |
|
第2步:加载KeyStore对象
KeyStore类的**load()**方法接受表示密钥库文件的FileInputStream对象和指定KeyStore密码的String参数。
通常,KeyStore存储在名为cacerts的文件中,位于C:/Program Files/Java/jre1.8.0_101/lib/security/ ,其默认密码为changeit ,使用**load()**方法加载它,如图所示下面。
1 |
|
第3步:创建KeyStore.ProtectionParameter对象
实例化KeyStore.ProtectionParameter,如下所示
1 |
|
第4步:创建一个SecretKey对象
通过实例化其Sub类SecretKeySpec创建SecretKey (接口)对象。 在实例化时,您需要将密码和算法作为参数传递给其构造函数,如下所示。
1 |
|
第5步:创建一个SecretKeyEntry对象
通过传递在上面步骤中创建的SecretKey对象来创建SecretKeyEntry类的对象,如下所示。
1 |
|
步骤6:设置KeyStore的条目
KeyStore类的**setEntry()**方法接受表示密钥库条目别名的String参数, SecretKeyEntry对象,ProtectionParameter对象,并将条目存储在给定别名下。
使用**setEntry()**方法将条目设置为密钥库,如下所示。
1 |
|
Example
以下示例将密钥存储到“cacerts”文件(Windows 10操作系统)中存在的密钥库中。
1 |
|
Java Cryptography - Retrieving keys
在本章中,我们将学习如何使用Java Cryptography从密钥库中检索密钥。
要从密钥库中检索密钥,请按照以下步骤操作。
第1步:创建KeyStore对象
java.security包的KeyStore类的**getInstance()**方法接受表示密钥库类型的字符串值,并返回KeyStore对象。
使用此方法创建KeyStore类的对象,如下所示。
1 |
|
第2步:加载KeyStore对象
KeyStore类的load()方法接受表示密钥库文件的FileInputStream对象和指定KeyStore密码的String参数。
通常,KeyStore存储在名为cacerts的文件中,位于C:/Program Files/Java/jre1.8.0_101/lib/security/ ,其默认密码为changeit ,使用**load()**方法加载它,如图所示下面。
1 |
|
第3步:创建KeyStore.ProtectionParameter对象
实例化KeyStore.ProtectionParameter,如下所示。
1 |
|
第4步:创建一个SecretKey对象
通过实例化其Sub类SecretKeySpec创建SecretKey (接口)对象。 在实例化时,您需要将密码和算法作为参数传递给其构造函数,如下所示。
1 |
|
第5步:创建一个SecretKeyEntry对象
通过传递在上面步骤中创建的SecretKey对象来创建SecretKeyEntry类的对象,如下所示。
1 |
|
第6步:设置KeyStore的条目
KeyStore类的**setEntry()**方法接受表示密钥库条目别名的String参数, SecretKeyEntry对象,ProtectionParameter对象,并将条目存储在给定别名下。
使用**setEntry()**方法将条目设置为密钥库,如下所示。
1 |
|
第7步:创建KeyStore.SecretKeyEntry对象
KeyStore类的getEntry()方法接受别名(String参数),并将ProtectionParameter类的对象作为参数,并返回KeyStoreEntry对象,然后将其转换为KeyStore.SecretKeyEntry对象。
通过将必需键的别名和前面步骤中创建的保护参数对象传递给**getEntry()**方法,创建KeyStore.SecretKeyEntry类的对象,如下所示。
1 |
|
步骤8:创建检索到的条目的密钥对象
SecretKeyEntry类的**getSecretKey()**方法返回一个SecretKey对象。 使用此方法创建一个SecretKey对象,如下所示。
1 |
|
例子 (Example)
以下示例显示了如何从密钥库中检索密钥。 在这里,我们将密钥存储在密钥库中,该密钥库位于“cacerts”文件(Windows 10操作系统)中,检索它,并显示它的一些属性,例如用于生成密钥的算法,以及格式检索到的密钥。
1 |
|
Java Cryptography - KeyGenerator
Java提供了KeyGenerator类,该类用于生成密钥,此类的对象是可重用的。
要使用KeyGenerator类生成密钥,请按照以下步骤操作。
第1步:创建KeyGenerator对象
KeyGenerator类提供**getInstance()**方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyGenerator对象。
使用getInstance()方法创建KeyGenerator对象,如下所示。
1 |
|
第2步:创建SecureRandom对象
java.Security包的SecureRandom类提供了一个强大的随机数生成器,用于在Java中生成随机数。 实例化此类,如下所示。
1 |
|
第3步:初始化KeyGenerator
KeyGenerator类提供了一个名为init()方法,此方法接受SecureRandom对象并初始化当前的KeyGenerator 。
使用**init()方法init()**在上一步中创建的KeyGenerator对象。
1 |
|
例子 (Example)
下面的示例演示了使用javax.crypto包的KeyGenerator类生成密钥的密钥。
1 |
|
Java Cryptography - KeyPairGenerator
Java提供了KeyPairGenerator类。 此类用于生成公钥和私钥对。 要使用KeyPairGenerator类生成密钥,请按照以下步骤操作。
第1步:创建KeyPairGenerator对象
KeyPairGenerator类提供**getInstance()**方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyPairGenerator对象。
使用getInstance()方法创建KeyPairGenerator对象,如下所示。
1 |
|
第2步:初始化KeyPairGenerator对象
KeyPairGenerator类提供了一个名为**initialize()**方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。
使用此方法初始化在上一步中创建的KeyPairGenerator对象,如下所示。
1 |
|
第3步:生成KeyPairGenerator
您可以使用KeyPairGenerator类的generateKeyPair()方法生成KeyPair 。 使用此方法生成密钥对,如下所示。
1 |
|
第4步:获取私钥/公钥
您可以使用**getPrivate()**方法从生成的KeyPair对象中获取私钥,如下所示。
1 |
|
您可以使用**getPublic()**方法从生成的KeyPair对象获取公钥,如下所示。
1 |
|
例子 (Example)
下面的示例演示了使用javax.crypto包的KeyPairGenerator类生成密钥的密钥。
1 |
|
Java Cryptography - Creating Signature
数字签名允许我们验证签名的作者,日期和时间,验证消息内容。 它还包括用于其他功能的身份验证功能。
数字签名的优点
在本节中,我们将了解要求使用数字签名的不同原因。 将数字签名实施到通信有几个原因 -
身份验证 (Authentication)
数字签名有助于验证消息来源。 例如,如果银行的分支机构向中央办公室发送消息,请求更改帐户余额。 如果中央办公室无法验证从授权来源发送的消息,则执行此类请求可能是一个严重的错误。
完整性 (Integrity)
邮件签名后,邮件中的任何更改都将使签名无效。
Non-repudiation
通过此属性,任何已签署某些信息的实体都不能在以后拒绝签名。
创建数字签名
现在让我们学习如何创建数字签名。 您可以按照以下步骤使用Java创建数字签名。
第1步:创建KeyPairGenerator对象
KeyPairGenerator类提供**getInstance()**方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyPairGenerator对象。
使用getInstance()方法创建KeyPairGenerator对象,如下所示。
1 |
|
第2步:初始化KeyPairGenerator对象
KeyPairGenerator类提供了一个名为**initialize()**方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。
使用**initialize()方法initialize()**在上一步中创建的KeyPairGenerator对象,如下所示。
1 |
|
第3步:生成KeyPairGenerator
您可以使用generateKeyPair()方法生成KeyPair 。 使用**generateKeyPair()**方法生成密钥对,如下所示。
1 |
|
第4步:从对中获取私钥
您可以使用**getPrivate()**方法从生成的KeyPair对象中获取私钥。
使用**getPrivate()**方法获取私钥,如下所示。
1 |
|
第5步:创建签名对象
Signature类的**getInstance()**方法接受表示所需签名算法的字符串参数,并返回相应的Signature对象。
使用**getInstance()**方法创建Signature类的对象。
1 |
|
第6步:初始化Signature对象
Signature类的initSign()方法接受PrivateKey对象并初始化当前的Signature对象。
使用**initSign()**方法初始化在上一步中创建的Signature对象,如下所示。
1 |
|
第7步:将数据添加到Signature对象
Signature类的**update()**方法接受表示要签名或验证的数据的字节数组,并使用给定的数据更新当前对象。
通过以字节数组的形式将要签名的数据传递给**update()方法来update()**初始化的Signature对象,如下所示。
1 |
|
第8步:计算签名
Signature类的**sign()**方法返回更新数据的签名字节。
使用**sign()**方法计算签名,如下所示。
1 |
|
Example
以下Java程序接受来自用户的消息并为给定消息生成数字签名。
1 |
|
Java Cryptography - Verifying Signature
您可以使用Java创建数字签名,并按照以下步骤进行验证。
第1步:创建KeyPairGenerator对象
KeyPairGenerator类提供**getInstance()**方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyPairGenerator对象。
使用getInstance()方法创建KeyPairGenerator对象,如下所示。
1 |
|
第2步:初始化KeyPairGenerator对象
KeyPairGenerator类提供了一个名为**initialize()**方法的方法。 此方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。
使用**initialize()方法initialize()**在上一步中创建的KeyPairGenerator对象,如下所示。
1 |
|
第3步:生成KeyPairGenerator
您可以使用generateKeyPair()方法生成KeyPair 。 使用此方法生成密钥对,如下所示。
1 |
|
第4步:从对中获取私钥
您可以使用**getPrivate()**方法从生成的KeyPair对象中获取私钥。
使用**getPrivate()**方法获取私钥,如下所示。
1 |
|
第5步:创建签名对象
Signature类的**getInstance()**方法接受表示所需签名算法的字符串参数,并返回相应的Signature对象。
使用**getInstance()**方法创建Signature类的对象。
1 |
|
第6步:初始化Signature对象
Signature类的initSign()方法接受PrivateKey对象并初始化当前的Signature对象。
使用**initSign()**方法初始化在上一步中创建的Signature对象,如下所示。
1 |
|
第7步:将数据添加到Signature对象
Signature类的**update()**方法接受表示要签名或验证的数据的字节数组,并使用给定的数据更新当前对象。
通过以字节数组的形式将要签名的数据传递给**update()方法来update()**初始化的Signature对象,如下所示。
1 |
|
第8步:计算签名
Signature类的**sign()**方法返回更新数据的签名字节。
使用sign()方法计算签名,如下所示。
1 |
|
第9步:初始化签名对象以进行验证
要验证Signature对象,首先需要使用initVerify()方法对其进行初始化,该方法接受PublicKey对象。
因此,使用**initVerify()**方法初始化Signature对象以进行验证,如下所示。
1 |
|
第10步:更新要验证的数据
使用更新方法使用要验证的数据更新初始化(用于验证)对象,如下所示。
1 |
|
第11步:验证签名
Signature类的**verify()**方法接受另一个签名对象并使用当前签名对象进行验证。 如果匹配发生,则返回true,否则返回false。
使用此方法验证签名,如下所示。
1 |
|
例子 (Example)
以下Java程序接受来自用户的消息,为给定消息生成数字签名并进行验证。
1 |
|
Java Cryptography - Encrypting Data
您可以使用javax.crypto包的Cipher类加密给定数据。 按照下面给出的步骤使用Java加密给定的数据。
第1步:创建KeyPairGenerator对象
KeyPairGenerator类提供**getInstance()**方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyPairGenerator对象。
使用getInstance()方法创建KeyPairGenerator对象,如下所示。
1 |
|
第2步:初始化KeyPairGenerator对象
KeyPairGenerator类提供了一个名为**initialize()**方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。
使用**initialize()方法initialize()**在上一步中创建的KeyPairGenerator对象,如下所示。
1 |
|
第3步:生成KeyPairGenerator
您可以使用KeyPairGenerator类的generateKeyPair()方法生成KeyPair 。 使用此方法生成密钥对,如下所示。
1 |
|
第4步:获取公钥
您可以使用getPublic()方法从生成的KeyPair对象获取公钥,如下所示。
使用此方法获取公钥,如下所示。
1 |
|
第5步:创建一个Cipher对象
Cipher类的**getInstance()**方法接受表示所需转换的String变量,并返回实现给定转换的Cipher对象。
使用**getInstance()**方法创建Cipher对象,如下所示。
1 |
|
第6步:初始化Cipher对象
Cipher类的**init()**方法接受两个参数,一个表示操作模式的整数参数(加密/解密)和一个表示公钥的Key对象。
使用**init()**方法初始化Cypher对象,如下所示。
1 |
|
第7步:将数据添加到Cipher对象
Cipher类的**update()**方法接受表示要加密的数据的字节数组,并使用给定的数据更新当前对象。
通过以字节数组的形式将数据传递给**update()方法来update()**初始化的Cipher对象,如下所示。
1 |
|
第8步:加密数据
Cipher类的**doFinal()**方法完成加密操作。 因此,使用此方法完成加密,如下所示。
1 |
|
例子 (Example)
以下Java程序接受来自用户的文本,使用RSA算法对其进行加密,并打印给定文本的加密格式。
1 |
|
Java Cryptography - Decrypting Data
您可以使用javax.crypto包的Cipher类解密加密数据。 按照下面给出的步骤使用Java解密给定数据。
第1步:创建KeyPairGenerator对象
KeyPairGenerator类提供**getInstance()**方法,该方法接受表示所需密钥生成算法的String变量,并返回生成密钥的KeyPairGenerator对象。
使用getInstance()方法创建KeyPairGenerator对象,如下所示。
1 |
|
第2步:初始化KeyPairGenerator对象
KeyPairGenerator类提供了一个名为**initialize()**方法,该方法用于初始化密钥对生成器。 此方法接受表示密钥大小的整数值。
使用**initialize()方法initialize()**在上一步中创建的KeyPairGenerator对象,如下所示。
1 |
|
第3步:生成KeyPairGenerator
您可以使用KeyPairGenerator类的generateKeyPair()方法生成KeyPair 。 使用此方法生成密钥对,如下所示。
1 |
|
第4步:获取公钥
您可以使用**getPublic()**方法从生成的KeyPair对象获取公钥,如下所示。
1 |
|
第5步:创建一个Cipher对象
Cipher类的**getInstance()**方法接受表示所需转换的String变量,并返回实现给定转换的Cipher对象。
使用**getInstance()**方法创建Cipher对象,如下所示。
1 |
|
第6步:初始化Cipher对象
Cipher类的**init()**方法接受两个参数
- 表示操作模式的整数参数(加密/解密)
- 表示公钥的关键对象
使用**init()**方法初始化Cypher对象,如下所示。
1 |
|
第7步:将数据添加到Cipher对象
Cipher类的**update()**方法接受表示要加密的数据的字节数组,并使用给定的数据更新当前对象。
通过以字节数组的形式将数据传递给**update()方法来update()**初始化的Cipher对象,如下所示。
1 |
|
第8步:加密数据
Cipher类的**doFinal()**方法完成加密操作。 因此,使用此方法完成加密,如下所示。
1 |
|
第9步:初始化Cipher对象以进行解密
要解密前面步骤中加密的密码,您需要初始化它以进行解密。
因此,通过传递参数Cipher.DECRYPT_MODE和PrivateKey对象来初始化密码对象,如下所示。
1 |
|
第10步:解密数据
最后,使用**doFinal()**方法解密加密文本,如下所示。
1 |
|
例子 (Example)
以下Java程序接受来自用户的文本,使用RSA算法对其进行加密,打印给定文本的密码,解密密码并再次打印解密文本。
1 |
|
参考:https://iowiki.com/java_cryptography/java_cryptography_quick_guide.html