大家好,欢迎来到IT知识分享网。
文章目录
几种图片加密方式及其原理
1.图片隐写AES加密:
JPEG文件处理和加密数据的嵌入
综上所述,通过将AES加密的数据嵌入到JPEG文件的非图像部分,这个过程不仅保证了数据的机密性和安全性,而且保持了图片的可视性和使用的灵活性。这种加密方法利用了JPEG格式的特性和AES算法的安全性,为敏感或私人数据的存储和传输提供了一个隐蔽且安全的解决方案。
加密步骤
- 参数和文件检查:检查输入的图片路径和输出路径,确认文件存在并且输出路径有效。
- 文件处理:
- 删除已经存在的加密文件,保证每次加密都是在干净的环境下进行。
- 生成一个随机AES密钥,用于加密图片数据。
- 生成加密文件头:
- 创建一个文件头,包括随机AES密钥和可能的其他元数据(如原始文件长度和哈希值)。
- 将加密文件头写入输出文件。
- AES加密图像数据:
- 使用AES密钥对原始图片文件进行加密。
- 加密的数据被追加到包含文件头的输出文件中。
- 处理JPEG文件:
- 如果加密后的总长度小于预定义的最小JPEG文件长度,将填充数据添加到加密数据中,直到达到这个最小长度。
- 选择一个目标JPEG文件,并将加密数据(包括文件头、加密图像数据和任何填充数据)嵌入到这个JPEG文件中,可能是通过添加到JPEG的评论段。
- 位置查找和数据插入:
- 在JPEG文件中找到适合插入加密数据的位置。
- 将加密数据插入到JPEG文件的指定位置,这可能涉及到对JPEG文件进行修改,如添加或扩展评论段。
- 文件复制和清理:
- 将修改后的JPEG文件复制到最终的输出路径。
- 删除临时文件和不再需要的加密数据文件。
- 错误处理:在整个过程中,如果遇到错误(如文件操作失败、加密错误等),将执行相应的错误处理逻辑,可能包括回滚操作、删除临时文件等。
伪代码:
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class JPEGSteganography {
public static void main(String[] args) {
try {
// 1. 生成 AES 密钥 SecretKey aesKey = generateAESKey(); // 2. 要加密的数据 byte[] dataToEncrypt = "Sensitive information".getBytes(); // 3. 加密数据 byte[] encryptedData = encryptData(dataToEncrypt, aesKey); // 4. 嵌入加密数据到 JPEG 文件 File jpegFile = new File("input_image.jpg"); // 原 JPEG 文件路径 embedDataIntoJPEG(jpegFile, encryptedData); System.out.println("加密数据已成功嵌入到 JPEG 文件中。"); } catch (Exception e) {
e.printStackTrace(); } } public static SecretKey generateAESKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); // 可以使用 128, 192, 或 256 位密钥 return keyGen.generateKey(); } public static byte[] encryptData(byte[] data, SecretKey aesKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, aesKey); return cipher.doFinal(data); } public static void embedDataIntoJPEG(File jpegFile, byte[] encryptedData) throws IOException {
// Step 1: 读取 JPEG 文件内容 FileInputStream fis = new FileInputStream(jpegFile); byte[] jpegContent = new byte[(int) jpegFile.length()]; fis.read(jpegContent); fis.close(); // Step 2: 创建 JPEG 注释段 byte[] commentSegment = createCommentSegment(encryptedData); // Step 3: 将注释段嵌入 JPEG 内容 byte[] modifiedJPEG = new byte[jpegContent.length + commentSegment.length]; System.arraycopy(jpegContent, 0, modifiedJPEG, 0, jpegContent.length); System.arraycopy(commentSegment, 0, modifiedJPEG, jpegContent.length, commentSegment.length); // Step 4: 保存修改后的 JPEG 文件 FileOutputStream fos = new FileOutputStream("modified_" + jpegFile.getName()); fos.write(modifiedJPEG); fos.close(); } public static byte[] createCommentSegment(byte[] encryptedData) {
// 创建注释段格式:0xFF 0xFE + 数据长度 + 数据内容 int length = encryptedData.length + 2; // 长度包含头部 byte[] commentSegment = new byte[length + 2]; commentSegment[0] = (byte) 0xFF; commentSegment[1] = (byte) 0xFE; // 注释段标识 commentSegment[2] = (byte) ((length >> 8) & 0xFF); // 高字节 commentSegment[3] = (byte) (length & 0xFF); // 低字节 System.arraycopy(encryptedData, 0, commentSegment, 4, encryptedData.length); return commentSegment; } }
2.RSA+AES加密
加密步骤
- 生成 RSA 密钥对
在这里插入代码片
import java.security.KeyPair; import java.security.KeyPairGenerator; public class RSAUtils {
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); return keyGen.generateKeyPair(); } }
- 生成 AES 密钥
import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; public class AESUtils {
public static SecretKey generateAESKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); return keyGen.generateKey(); } }
- AES 加密数据
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; public class AESUtils {
public static byte[] encryptData(byte[] data, SecretKey aesKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] iv = new byte[cipher.getBlockSize()]; new SecureRandom().nextBytes(iv); IvParameterSpec ivParams = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParams); byte[] encrypted = cipher.doFinal(data); return concatenateArrays(iv, encrypted); } private static byte[] concatenateArrays(byte[] a, byte[] b) {
byte[] result = new byte[a.length + b.length]; System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length); return result; } }
- 使用 RSA 加密 AES 密钥
import javax.crypto.Cipher; public class RSAUtils {
public static byte[] encryptAESKey(SecretKey aesKey, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(aesKey.getEncoded()); } }
- 使用 RSA 加密 AES 密钥
public class EncryptionProcess {
public static void main(String[] args) throws Exception {
// 生成 RSA 密钥对 KeyPair keyPair = RSAUtils.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); // 生成 AES 密钥 SecretKey aesKey = AESUtils.generateAESKey(); // 明文数据 byte[] plaintextData = "Sensitive Information".getBytes(); // 使用 AES 加密数据 byte[] encryptedData = AESUtils.encryptData(plaintextData, aesKey); // 使用 RSA 加密 AES 密钥 byte[] encryptedAESKey = RSAUtils.encryptAESKey(aesKey, publicKey); // 发送 encryptedData 和 encryptedAESKey // 此处可使用 HTTP POST 或其他方式发送加密数据和 AES 密钥 } }
伪造文件头
function createFakeImageFile(encryptedData) {
// Step 1: 定义 JPEG 文件头 byte[] jpegHeader = new byte[] {
(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE0 }; // Step 2: 创建输出文件 File outputFile = new File("fake_image.jpg"); FileOutputStream fos = new FileOutputStream(outputFile); // Step 3: 写入伪造的 JPEG 文件头 fos.write(jpegHeader); // Step 4: 写入加密后的图像数据 fos.write(encryptedData); // Step 5: 关闭文件输出流 fos.close(); }
扩展:对视频文件的加密
可以用aes+rsa对视频文件进行加密,我们可以添加文件头让系统将加密后的文件识别为视频文件。
- 理解 MP4 文件格式
MP4 文件由多个不同的盒子(Box)组成,每个盒子都有其特定的结构。MP4 文件的起始部分通常包含以下几个重要的文件头盒子:
- 伪造 MP4 文件头的步骤
伪代码示例:
function createFakeMP4File(encryptedData) {
// Step 1: 定义 MP4 文件头 (ftyp + moov) byte[] mp4Header = new byte[] {
0x00, 0x00, 0x00, 0x20, // ftyp size 0x66, 0x74, 0x79, 0x70, // ftyp 0x69, 0x73, 0x6f, 0x6D, // isom 0x00, 0x00, 0x00, 0x00, // version + flags 0x00, 0x00, 0x00, 0x1C, // moov size 0x6D, 0x6F, 0x6F, 0x76 // moov // 这里可以添加更多有效的 MP4 文件头数据 }; // Step 2: 创建输出文件 File outputFile = new File("fake_video.mp4"); FileOutputStream fos = new FileOutputStream(outputFile); // Step 3: 写入伪造的 MP4 文件头 fos.write(mp4Header); // Step 4: 写入加密后的视频数据 fos.write(encryptedData); // Step 5: 关闭文件输出流 fos.close(); }
3.图片猫脸变换
广义Arnold变换是一种针对非方形图像的图像置乱技术,它扩展了传统Arnold变换的应用范围,使其能够处理非正方形的图像。这种方法通过对非方形图像进行智能分割,将图像分成多个接近正方形的小区块,然后对每个小区块独立进行Arnold变换。此技术考虑到非方形图像在长宽比上的差异,通过分段处理确保变换能够均匀地覆盖到图像的每一个部分,包括任何可能的长边剩余部分。
具体实现中,首先判断图像是否为正方形:如果是,直接进行标准的Arnold变换;如果不是,则根据图像的长宽比确定分割的小区块尺寸。分割后,计算每个区块的偏移量,并对每个区块单独应用Arnold变换。这一过程可能会根据需要重复多次,以确保变换的效果。如果在图像的长边上存在剩余部分未被完全覆盖,该方法也会对这些剩余部分进行特别处理,确保整个图像都经过了均匀的变换处理。
该方法的优点在于,它允许非方形图像通过分割成多个小的正方形或接近正方形的区块来利用Arnold变换的优势,从而实现对图像的有效加密和混淆。这种策略不仅提高了Arnold变换在非方形图像上的适用性和效果,还保持了变换的核心目的——增加图像的隐蔽性和复杂度,使其在图像加密、数字水印和其他需要图像处理的应用领域中具有广泛的应用前景。
广义Arnold变换是一种在数字图像加密领域常用的技术,旨在通过对图像像素位置进行数学上的置乱操作,以保护图像内容的安全性。该变换依赖于两个关键参数,通常表示为(a)和(b),这些参数直接影响像素位置的置乱模式。变换过程涉及将每个像素的坐标((x, y))按照特定的数学公式重新计算,以确定像素在加密图像中的新位置((x’, y’))。
具体来说,广义Arnold变换通过以下公式确定像素的新位置:
其中,(N)代表图像的尺寸,而(a, b, c, d)是变换的参数。取模运算(\mod)确保新计算出的像素位置位于图像的有效范围内。
这种置乱过程的一个关键特性是其可逆性。也就是说,通过应用逆向的Arnold变换,可以从加密图像中恢复出原始图像的像素排列。这种特性确保了加密图像可以被有效地解密,前提是解密者知道正确的变换参数和次数。
在图像加密的上下文中,广义Arnold变换的作用是将原始图像的像素位置打乱,以至于在没有解密密钥的情况下,任何人观看图像都无法辨认出原始内容。这种方法不仅增强了图像的安全性,也为确保敏感信息不被未经授权的用户访问提供了一层重要的保护。
详细化加密流程步骤
- 输入验证与图像解码:
- 验证输入图像路径和输出路径的有效性,确保路径存在且输出文件不存在,避免覆盖已有文件。不合法或存在问题时,返回相应错误代码。
- 使用
BitmapUtil.decodeFile方法解码图像文件,将其转换为位图对象,为后续加密处理做好准备。
- 像素数组转换:
- 利用
BitmapUtil.bitmap2Array方法,将位图对象转换为像素数组。每个元素代表图像中一个像素点,便于后续的空间置乱处理。
- 利用
- 空间置乱处理(包括Arnold变换):
- 对像素数组执行空间置乱处理,通过一系列算法改变像素的空间分布,包括简单的像素交换和基于复杂数学函数的变换。
- 使用Arnold变换方法,进行广义猫脸变换。这是一种特定的空间置乱技术,适用于改变像素点的空间位置,进而加密图像。
- 输出加密图像:
- 将加密和包装处理后的图像数据写入指定的输出路径,完成加密流程。
根据加密流程的描述和所提供的代码,解密步骤需要逆向执行加密过程中的操作。这包括Arnold变换的逆变换以及其他可能应用的像素置乱和转换方法的反向操作。以下是一个基于加密流程的解密步骤概述:
- 输入验证与图像解码
- 验证输入加密图像路径的有效性,确保路径存在。不合法或存在问题时,返回相应错误代码。
- 使用适当的方法解码加密图像文件,将其转换为位图对象,为后续解密处理做好准备。
- 像素数组转换
- 利用适当的方法,将位图对象转换为像素数组。这一步骤与加密流程中的像素数组转换相同,目的是获得方便进行数学运算的像素数据格式。
- 空间置乱处理的逆向操作
- 对于应用的空间置乱处理,包括Arnold变换,在解密过程中需要执行相反的操作来恢复原始图像。这可能包括执行与加密过程中相同数量的逆Arnold变换迭代,以便将像素恢复到它们的原始位置。
- Arnold变换是可逆的,因此通过执行足够次数的逆变换(逆操作),可以恢复原始图像。通常,这意味着对于每次加密中执行的Arnold变换,解密时也需要执行相同次数的逆Arnold变换。
- 像素数组到位图的转换
- 将经过逆向空间置乱处理的像素数组转换回位图格式。这一步骤是加密过程中像素数组转换步骤的直接逆操作,目的是从修改后的像素数据中恢复出可视的图像。
- 输出解密图像
- 将解密后的位图数据保存到指定的输出路径,完成解密流程。这一步骤确保用户可以访问和查看已解密的原始图像。
需要注意的是,解密过程的准确性和成功与加密过程中使用的确切参数(如Arnold变换的参数a、b和迭代次数)密切相关。因此,在解密时,必须使用与加密相同的参数值来确保图像能够正确恢复。
4.语音频谱置乱
这种加密方法的核心原理在于转换和打乱音频PCM(脉冲编码调制)数据,以保护语音通信的安全。该过程利用频率域和时间域的操作,利用傅里叶变换改变音频信号的频谱属性。具体来说,它通过在频率域对信号进行分组和重新排序,以及在时间域对帧进行置乱和重组,来对原始音频数据进行加密。这样不仅改变了音频数据的表现形式,还增加了无授权监听者解密和理解音频内容的难度。
加密原理主要基于傅里叶变换(FFT)和置乱算法。傅里叶变换是将音频信号从时域转换到频域,这使得音频数据的频率成分可以被分析和处理。在频域置乱阶段,通过对频率分量进行重新排序,改变了原始音频信号的频率分布,这种处理对音频的听感影响较小,但能有效提高加密强度。随后,进行时域置乱,即通过改变音频帧的顺序来进一步加密数据。时域置乱通过分组和重排这些组中的帧,打乱了原始音频信号在时间上的连续性。这两种置乱方法的结合,实现了对音频数据的有效加密,增加了音频数据被非授权解密的难度。
加密流程详解
- 采样和分帧
- 每次处理一个固定大小(1920字节)的数据块,这些数据块构成采样数组。随后,采样得到的数据根据预设的大小进行分帧处理。
- 频域置乱
- 每个采样数组通过快速傅里叶变换(FFT)转换到频域,生成频谱数组。在频谱数组中,特别关注
(20Hz,2kHz)和(2kHz, 4kHz)这两个关键频率区间。对这些区间内的频率成分执行平移和交换操作,并根据固定的秘钥数组进行加权处理。这一步骤生成了复杂的置乱数组,显著改变了原始信号的频率分布,达到了频域混淆的目的。这种重新排序改变了音频信号的频谱结构,但不改变音频内容的本质。
- 每个采样数组通过快速傅里叶变换(FFT)转换到频域,生成频谱数组。在频谱数组中,特别关注
- 逆变换
- 经过精心设计的频域置乱处理后,数据通过逆FFT转换回时间域。逆变换保留了数据的时间序列结构,为接下来的时域置乱作准备。
- 时域置乱
- 逆变换后的数据进一步经过时域置乱处理。根据密钥(timeEnKey)将音频帧分组,并在每个组内进行置乱。对于每个组内的音频帧,根据预设的密钥顺序进行重排,实现对音频数据时域上的置乱
.时域置乱增加了数据的不可预测性,进一步加强了加密的安全性。
- 逆变换后的数据进一步经过时域置乱处理。根据密钥(timeEnKey)将音频帧分组,并在每个组内进行置乱。对于每个组内的音频帧,根据预设的密钥顺序进行重排,实现对音频数据时域上的置乱
- 合帧输出加密数据
- 输出前通过合帧处理重新组合成完整的PCM数据流。考虑帧与帧之间的重叠和窗函数应用,确保加密音频的连贯性和质量。输出的加密音频数据替代原始PCM数据流,保障音频内容的保密性和完整性。
解密流程
解密过程是加密操作的逆向执行,确保只有授权的接收者能够准确地恢复音频内容:
- 时域反置乱:加密数据首先经过时域反置乱处理,恢复至置乱前的时间序列排列。
- FFT变换:接着,数据被转换到频域,准备进行频域反置乱。
- 频域反置乱:利用相同的密钥对频域数据进行精确的反置乱操作,尤其是针对
(20Hz,2kHz)和(2kHz, 4kHz)区间的特定处理,恢复原始的频率分布。 - 逆FFT变换:最后,数据通过逆FFT变换回时间域,得到解密后的音频信号。
- 输出解密数据:完成解密过程后,得到的时间域数据流便是原始的、未加密的音频信号,保证了数据的真实性和完整性。
通过在关键的频率区间进行精细的置乱和根据固定秘钥数组加权处理,这一加密方法不仅增强了音频数据的安全性,也保证了音频内容在授权的情况下能够被准确恢复。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120612.html