信息安全工程师-AES密码技术及XOR图像遮盖技术(JavaC++)
目錄
AES加密
編碼
異或XOR
加解密步驟
AES加密
從中可以知道對稱加密和公鑰密碼只能保護機密性,防止竊聽。
如果要完整性防篡改,需要用單向散列函數、消息認證碼、數字簽名技術。
這里有個關于對稱加密的一個問題:
如這個問題:對稱加密如AES。如果一串密文。有人稍微修了下。用密鑰去解會不會解出亂碼,還是解密失敗?拿java測。稍微測了幾次是解密失敗。但會不會有解出亂碼的情況?
問了一些大佬,最后總結出2個答案:
①一個鑰匙(密鑰)只能開一把鎖(加密數據)。但這樣就有一個問題既然是這樣的模式,那么這個AES,不就具備了一部分了簽名的能力,就可以防篡改了,比如https,最后是用了AES加密,那么這個數據用AES加密,是否能防篡改,而上圖中對稱加密只用來保障機密性。所以這個地方就有點矛盾了。
②亂碼和失敗都是有可能,關鍵看AES是那種加密模式,是如果修改數據的。如果是使用流模式加密,能解密,但解出來的都是亂碼。塊加密模式只要不修改最后一塊就能解密,解出來是亂碼,塊加密模式修改最后一個塊,填充校驗失敗,不能解密。
這里我做了個實驗如下代碼:
AES.java
Main.java
package cn.it1995.tool;import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer;public class Main {public static void main(String[] args) throws UnsupportedEncodingException {String content = "helloWorldHelloWorld111111111111111111111111";AES aes = new AES();byte[] encrypted = aes.encrypt(new String(content));byte[] decrypt = aes.decrypt(encrypted);System.out.println("encrypted:" + new String(encrypted));System.out.println("decrypt:" + new String(decrypt));System.out.println("----------------------------------");ByteBuffer bb = ByteBuffer.wrap(encrypted);byte[] cipher = new byte[32];bb.get(cipher, 0, 16);for(int i = 5; i < 10; i++){cipher[i] = 1;}for(int i = 0; i < 16; i++){cipher[16 + i] = encrypted[encrypted.length - 16 + i];}System.out.println("刪除(篡改)保留最后一塊:");System.out.println(new String(aes.decrypt(cipher)));} }運行截圖:
?所以AES并不能防篡改。如果要防篡改需要用單向散列函數、消息認證碼、數字簽名技術。
編碼
編碼:將現實世界中的東西映射為比特序列的操作。如midnight:
m->0110 1101
i->0110 1001
d->0110 0100
n->0110 1110
i->0110 1001
g->0110 0111
h->0110 1000
t->0111 0100
異或XOR
這個比較有意思以前的理解為相同為0,不同的為1,
這里看到了有人用棋盤翻轉的理解方式。
理解:0表示不翻轉,1表示翻轉。
0 XOR 0 = 0;沒有翻轉
1 XOR 0 = 1;翻轉了1次
0 XOR 1 = 1;翻轉了1次
1 XOR 1 = 0;翻轉了2次
加解密步驟
A XOR B = C
C XOR B = A
一串數據與密鑰運算,得到加密數據,加密數據在與密鑰運算獲取明文。
如下:
A:0100 1100
B:1010 1010
來計算一下:
A XOR B:
0100 1100
1010 1010
----------
1110 0110
結果 XOR B:
1110 0110
1010 1010
----------
0100 1100
這里有個結論:數據a異或數據b得到數據c,數據c再與數據數據b異或,可以得到數據a。
圖像是這樣的:
下面使用Qt來實現這個加密。
編程實例
程序運行截圖如下:
先是一個蠟筆小新的彩色圖:
?下面是《山坡羊·潼關懷古》
?原理就是上面說的,通過這種方式實現圖片掩蓋。這里水印也可以這么搞。
工程如下:
源碼如下:
Widget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;uchar *m_secPtr;uchar *m_xorPtr;uchar *m_retPtr; }; #endif // WIDGET_H?Widget.cpp
#include "Widget.h" #include "ui_Widget.h" #include <QImage> #include <QDebug> #include <QRandomGenerator>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);QImage pix(":/tghg.png");uchar *oriPtr = pix.bits();int picSize = pix.sizeInBytes();m_secPtr = new uchar[picSize];m_xorPtr = new uchar[picSize];m_retPtr = new uchar[picSize];//生成密鑰圖片for(int i = 0; i < picSize; i++){m_secPtr[i] = QRandomGenerator::global()->bounded(256);}ui->originLabel->setPixmap(QPixmap::fromImage(pix));ui->secLabel->setPixmap(QPixmap::fromImage(QImage(m_secPtr, pix.width(), pix.height(), pix.format())));for(int i = 0; i < picSize; i++){m_xorPtr[i] = oriPtr[i] ^ m_secPtr[i];}ui->xorLabel->setPixmap(QPixmap::fromImage(QImage(m_xorPtr, pix.width(), pix.height(), pix.format())));//還原for(int i = 0; i < picSize; i++){m_retPtr[i] = m_xorPtr[i] ^ m_secPtr[i];}ui->retLabel->setPixmap(QPixmap::fromImage(QImage(m_retPtr, pix.width(), pix.height(), pix.format()))); }Widget::~Widget() {delete ui;delete this->m_retPtr;delete this->m_secPtr;delete this->m_xorPtr; }main.cpp
#include "Widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }源碼打包下載地址:
Qt/XorPic at master · fengfanchen/Qt · GitHub
總結
以上是生活随笔為你收集整理的信息安全工程师-AES密码技术及XOR图像遮盖技术(JavaC++)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fiddler工具杂记-将某些数据收集起
- 下一篇: Java笔记-对称加密AES的使用