精华内容
下载资源
问答
  • 信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是透明的。传统的信息隐藏起源于古老的隐写术。如在古希腊战争中,为了安全地传送军事情报,奴隶主...

    信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是透明的。

    传统的信息隐藏起源于古老的隐写术。如在古希腊战争中,为了安全地传送军事情报,奴隶主剃光奴隶 的头发,将情报文在奴隶的头皮上,待头发长起后再派出去传送消息。我国古代也早有以藏头诗、藏尾诗、漏格诗以及绘画等形式,将要表达的意思和“密语”隐藏在诗文或画卷中的特定位置,一般人只注意诗或画的表面意境,而不会去注意或破解隐藏其中的密语。   信息隐藏的发展历史可以一直追溯到"匿形术(Steganography)"的使用。"匿形术"一词来源于古希腊文中"隐藏的"和"图形"两个词语的组合。虽然"匿形术"与"密码术(Cryptography)"都是致力于信息的保密技术,但是,两者的设计思想却完全不同。"密码术"主要通过设计加密技术,使保密信息不可读,但是对于非授权者来讲,虽然他无法获知保密信息的具体内容,却能意识到保密信息的存在。而"匿形术"则致力于通过设计精妙的方法,使得非授权者根本无从得知保密信息的存在与否。相对于现代密码学来讲,信息隐藏的最大优势在于它并不限制对主信号的存取和访问,而是致力于签字信号的安全保密性。

     

     

    我们进行信息交换的时候,需要保证数据的安全,所以需要进行适当的信息隐藏。

    我们发送一个图片。但是图片里面隐含的加密信息,是就是信息隐藏,只有专属工具能够读出。

    所以信息隐藏技术很重要。针对信息安全。

    我们来实现一个案例代码。

    BMP图信息隐藏头文件,请见代码分析

    // BMPHider.h: interface for the CBMPHider class.
    //
    //
    
    #if !defined(AFX_BMPHIDER_H__6287D87F_F0AA_4D0C_9502_4674B639CBB5__INCLUDED_)
    #define AFX_BMPHIDER_H__6287D87F_F0AA_4D0C_9502_4674B639CBB5__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include <complex>
    using namespace std;
    class CBMPHider  
    {
    public:
    	CBMPHider();
    	virtual ~CBMPHider();
    public:
    	int m_BitCount;			//位图的图像位数
    	WORD * m_pWordData;
    	CPalette m_Palette;
    	unsigned char *m_pDib, *m_pDibBits;
    	unsigned char *m_pOldDibShow;
    	DWORD m_dwDibSize;
    	BITMAPINFOHEADER *m_pBIH;
    	RGBQUAD *m_pPalette;
    	int m_nPaletteEntries;
    	UINT bitmap_size;
    	UINT embfile_size;
    	unsigned char *p;		//指向宿主图像数据
    	int tag;				//此tag用以标记打开的图像中是否含有隐藏信息0:无 else:有
    	unsigned char *q;		//指向隐藏文件数据
    	unsigned char *m_pFile;
    public:
    	BOOL Draw( CDC *pDC, int nX = -1, int nY = -1, int nWidth = -1, int nHeight = -1, int Style = 1);
    	BOOL Save( const char *pszFilename );
    	BOOL Load( const char * );
    	
    	void BackUpDib();		//备份图像
    	void Pick();			//提取图像
    	void Embed();			//嵌入图像
    	BOOL LoadEmbFile(const char *);
    	BOOL DrawContrast(CDC *pDC,int rect_width, int rect_height);
    	void SavePicked( const char *pszFilename );	
    
    };
    
    #endif // !defined(AFX_BMPHIDER_H__6287D87F_F0AA_4D0C_9502_4674B639CBB5__INCLUDED_)


    请见详细代码实现

     

    #include "stdafx.h"
    #include "BMPHider.h"
    
    //
    // Construction/Destruction
    //
    
    CBMPHider::CBMPHider()
    {
    	m_pDib = NULL;
    	m_pWordData = NULL;
    	m_pFile = NULL;
    	m_pOldDibShow = NULL;
    }
    
    CBMPHider::~CBMPHider()
    {
    	if( m_pDib != NULL )
    		delete [] m_pDib;
    	if( m_pWordData != NULL )
    		delete [] m_pWordData;
    	if (m_pFile != NULL)
    		delete [] m_pFile;
    	if (m_pOldDibShow != NULL)
    		delete [] m_pOldDibShow;
    }
    
    BOOL CBMPHider::Load( const char *pszFilename )
    {
    	CFile cf;
    	if( !cf.Open( pszFilename, CFile::modeRead ) )
    		return( FALSE );
    	
    	DWORD dwDibSize;
    	dwDibSize =
    		cf.GetLength() - sizeof( BITMAPFILEHEADER );
    
    	unsigned char *pDib;
    	pDib = new unsigned char [dwDibSize];
    	if( pDib == NULL )
    		return( FALSE );
    
    	BITMAPFILEHEADER BFH;
    	try
    	{
    		if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
    			!= sizeof( BITMAPFILEHEADER ) ||
    			BFH.bfType != 'MB' ||
    			cf.Read( pDib, dwDibSize ) != dwDibSize )
    		{
    			delete [] pDib;
    			return( FALSE );
    		}
    	}
    	
    	catch( CFileException *e )
    	{
    		e->Delete();
    		delete [] pDib;
    		return( FALSE );
    	}
    	cf.Close();
    	if( m_pDib != NULL )
    		delete m_pDib;
    	if (BFH.bfReserved1 != 0)          //含有隐藏信息,保存其大小
    	{
    		if (BFH.bfReserved2 == 0)
    			embfile_size = BFH.bfReserved1;
    		else
    			embfile_size = BFH.bfReserved1 + 65535;
    	}
    	m_pDib = pDib;
    	m_dwDibSize = dwDibSize;
    	m_pBIH = (BITMAPINFOHEADER *) m_pDib;
    	m_pPalette =(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
    	m_nPaletteEntries = 1 << m_pBIH->biBitCount;
    	if( m_pBIH->biBitCount > 8 )         
    		m_nPaletteEntries = 0;
    	else if( m_pBIH->biClrUsed != 0 )
    		m_nPaletteEntries = m_pBIH->biClrUsed;
    	m_pDibBits = &m_pDib[sizeof(BITMAPINFOHEADER)+
    			m_nPaletteEntries*sizeof(RGBQUAD)];
    
    	if( m_Palette.GetSafeHandle() != NULL )
    		m_Palette.DeleteObject();
    
    	if( m_nPaletteEntries != 0 )
    	{      
    
    		LOGPALETTE *pLogPal = (LOGPALETTE *) new char
    				[sizeof(LOGPALETTE)+
    				m_nPaletteEntries*sizeof(PALETTEENTRY)];
    
    		if( pLogPal != NULL )
    		{
    			pLogPal->palVersion = 0x300;
    			pLogPal->palNumEntries = m_nPaletteEntries;
    
    			for( int i=0; i<m_nPaletteEntries; i++ )
    			{
    				pLogPal->palPalEntry[i].peRed =
    					m_pPalette[i].rgbRed;
    				pLogPal->palPalEntry[i].peGreen =
    					m_pPalette[i].rgbGreen;
    				pLogPal->palPalEntry[i].peBlue =
    					m_pPalette[i].rgbBlue;
    			}
    
    			m_Palette.CreatePalette( pLogPal );
    			delete [] pLogPal;
    		}
    	}
    
    	m_BitCount = 24;             //24位位图
    	p = m_pDibBits;              //指向位图数据的指针,用来执行处理操作用
    	bitmap_size = m_dwDibSize - (m_pDibBits - m_pDib);//真正的位图数据的大小(即除头结构外)
    	
    	tag = BFH.bfReserved1;
    	return( TRUE );
    
    }
    
    BOOL CBMPHider::Save( const char *pszFilename ) //保存含有隐藏信息的bmp
    {
    	if( m_pDib == NULL )
    		return( FALSE );
    	CFile cf;
    	if( !cf.Open( pszFilename,
    		CFile::modeCreate | CFile::modeWrite ) )
    		return( FALSE );
    	try
    	{
    		BITMAPFILEHEADER BFH;
    		memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
    		BFH.bfType = 'MB';
    		BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
    		BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
    			sizeof( BITMAPINFOHEADER ) +
    			m_nPaletteEntries * sizeof( RGBQUAD );
    		if (embfile_size <= 65535)   
    			//由于bfReserved1是unsigned short型的,大小可能不能满足要求,可能要用到reserved2
    			BFH.bfReserved1 = embfile_size;   
    		else
    		{
    			BFH.bfReserved1 = embfile_size - 65535;
    			BFH.bfReserved2 = 1; //标记
    		}
    		cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
    		cf.Write( m_pDib, m_dwDibSize );
    	}
    	catch( CFileException *e )
    	{
    		e->Delete();
    		return( FALSE );
    	}
    	return( TRUE );
    }
    
    BOOL CBMPHider::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style )
    {
     	if( m_pDib == NULL )
    		return( FALSE );
     	long vWidth = m_pBIH->biWidth;
     	if( nWidth == -1 )
     		nWidth = m_pBIH->biWidth;
    	if( nHeight == -1 )
     		nHeight = m_pBIH->biHeight;
     	if (Style)   
     	{
     		StretchDIBits( pDC->m_hDC, nX, nY,
     			nWidth, nHeight,
     			0, 0,
     			m_pBIH->biWidth, m_pBIH->biHeight,
     			m_pDibBits,
     			(BITMAPINFO *) m_pBIH,
    			BI_RGB, SRCCOPY );
     	}
     	else
     	{
    		SetDIBitsToDevice( pDC->m_hDC, nX, nY,
     			m_pBIH->biWidth, m_pBIH->biHeight,
    			0, 0,
     			0, m_pBIH->biHeight,
     			m_pDibBits,
     			(BITMAPINFO *) m_pBIH,
     			BI_RGB);
     	}
    	return( TRUE );
    }
    
    
    
    BOOL CBMPHider::LoadEmbFile(const char * pszFilename)
    {	
    	CFile cf;
    	if( !cf.Open( pszFilename, CFile::modeRead ) )
    		return( FALSE );
    
    	DWORD dwFileSize;
    	dwFileSize = cf.GetLength();
    
    	embfile_size = dwFileSize;
    	unsigned char *pFile;
    	pFile = new unsigned char [dwFileSize];
    	cf.Read( pFile, dwFileSize );       //将文件中内容读入数组,解下来就开始嵌入操作
    
    	m_pFile = pFile;
    	q = pFile;        //记录下位置
    	return true;
    }
    
    void CBMPHider::Embed()//嵌入
    {
    	unsigned char bmdata;//bitmap data
    	unsigned char efdata;//embeddedfile data
    	int t = 7;		
    	int x[8];	
    	int s[8];
    	int last_bit; //记录字节最低位本来的bit
    
    	for(UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
    	{
    		bmdata = *p;
    
    		for (int j = 0; j <= 7; j++) //计算各bit位
    		{
    			x[j] = bmdata & 1;
    			bmdata >>= 1;
    		}
    		
    		last_bit = x[0];
    		x[0] = x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
    		
    		if (t == 7)    //宿主图片每走过八个字节,计算一次s[]
    		{
    			efdata = *q;
    			for (j = 0; j <= 7; j++)
    			{
    				s[j] = efdata & 1;
    				efdata >>= 1;
    			}
    		}
    		x[0] ^= s[t];//隐藏信息
    		if (last_bit == 0)  //嵌入隐藏信息
    		{
    			*p |= x[0];
    		}
    		else
    		{
    			*p &= 254 + x[0];
    		}
    	
    		p++;
    		t--;
    		if (t == -1)  //需要计算一次s[]
    		{
    			t = 7;
    			q++;
    			i2++;
    		}
    	}
    
    }
    
    void CBMPHider::Pick()//提取
    {
    	m_pFile = new unsigned char [embfile_size];
    	unsigned char *q = m_pFile;
    
    	unsigned char bmdata;//bitmap data
    
    	int x[8];	
    	int s[8];
    	int t = 7;
    	for (UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
    	{
    		bmdata = *p;
    		for (int j = 0; j <= 7; j++) //计算各bit位
    		{
    			x[j] = bmdata & 1;
    			bmdata >>= 1;
    		}
    		s[t] = x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
    		t--;
    		if (t == -1) //s[7]到s[0]组成一个字节
    		{
    			*q = s[7] * 128 + s[6] * 64 + s[5] * 32 + s[4] * 16 + 
    				s[3] * 8 + s[2] * 4 + s[1] * 2 + s[0];
    			t = 7;
    			i2++;
    			q++;
    		}
    		p++;
    	}
    
    }
    	
    void CBMPHider::SavePicked( const char *pszFilename )
    {
    	CFile cf;
    	cf.Open( pszFilename, CFile::modeCreate | CFile::modeWrite );
    	cf.Write( m_pFile, embfile_size );
    }
    
    void CBMPHider::BackUpDib()
    {
    	m_pOldDibShow = new unsigned char [bitmap_size];
       
    	::CopyMemory(m_pOldDibShow, m_pDibBits, bitmap_size); //将原始的数据单独保存以便对比显示
    }
    
    BOOL CBMPHider::DrawContrast(CDC *pDC, int rect_width, int rect_height)
    {                             //看原图,如果容纳得下两个图,则不要压缩,否则要压缩
    	if (m_pOldDibShow == NULL)
    		return FALSE;
    	if (rect_width >= 2*m_pBIH->biWidth + 30 && rect_height >= m_pBIH->biHeight)
    	{
    		StretchDIBits( pDC->m_hDC, 0, 0,
    		m_pBIH->biWidth, m_pBIH->biHeight,
    		0, 0,
    		m_pBIH->biWidth, m_pBIH->biHeight,
    		m_pOldDibShow,
    		(BITMAPINFO *) m_pBIH,
    		BI_RGB, SRCCOPY );    // 原图
    
    		StretchDIBits( pDC->m_hDC, m_pBIH->biWidth+30, 0,
    		m_pBIH->biWidth, m_pBIH->biHeight,
    		0, 0,
    		m_pBIH->biWidth, m_pBIH->biHeight,
    		m_pDibBits,
    		(BITMAPINFO *) m_pBIH,
    		BI_RGB, SRCCOPY );    // 嵌入隐藏信息的图
    	}
    	else
    	{
    		int scale_i = m_pBIH->biWidth * 5 / (rect_width*2);
    		int scale_j = m_pBIH->biHeight / rect_height;
    		if (scale_i < scale_j)
    			scale_i = scale_j;
    
    		StretchDIBits( pDC->m_hDC, 0, 0,
    		m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
    		0, 0,
    		m_pBIH->biWidth, m_pBIH->biHeight,
    		m_pOldDibShow,
    		(BITMAPINFO *) m_pBIH,
    		BI_RGB, SRCCOPY );    // 原图
    
    		StretchDIBits( pDC->m_hDC, m_pBIH->biWidth / scale_i+30, 0,
    		m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
    		0, 0,
    		m_pBIH->biWidth, m_pBIH->biHeight,
    		m_pDibBits,
    		(BITMAPINFO *) m_pBIH,
    		BI_RGB, SRCCOPY );    // 嵌入隐藏信息的图
    
    	}
    
    	return TRUE;
    }


    具体代码调用实现

    #include "stdafx.h"
    #include "DataHideInBMP.h"
    
    #include "DataHideInBMPDoc.h"
    #include "DataHideInBMPView.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /
    // CDataHideInBMPView
    
    IMPLEMENT_DYNCREATE(CDataHideInBMPView, CView)
    
    BEGIN_MESSAGE_MAP(CDataHideInBMPView, CView)
    	//{{AFX_MSG_MAP(CDataHideInBMPView)
    	ON_COMMAND(ID_NORMAL, OnNormal)
    	ON_COMMAND(ID_STRETCH, OnStretch)
    	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
    	ON_COMMAND(ID_EMBED, OnEmbed)
    	ON_UPDATE_COMMAND_UI(ID_EMBED, OnUpdateEmbed)
    	ON_COMMAND(ID_PICK, OnPick)
    	ON_UPDATE_COMMAND_UI(ID_PICK, OnUpdatePick)
    	//}}AFX_MSG_MAP
    	// Standard printing commands
    	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
    	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    END_MESSAGE_MAP()
    
    /
    // CDataHideInBMPView construction/destruction
    
    CDataHideInBMPView::CDataHideInBMPView()
    {
    	// TODO: add construction code here
    	ImageStyle = 0;
        have_open_a_file = false;
    
    	embed = false;
    	pick = false;
    	show_contrast = false;
    }
    
    CDataHideInBMPView::~CDataHideInBMPView()
    {
    }
    
    BOOL CDataHideInBMPView::PreCreateWindow(CREATESTRUCT& cs)
    {
    	// TODO: Modify the Window class or styles here by modifying
    	//  the CREATESTRUCT cs
    	WNDCLASSEX wndcls;
    	wndcls.cbSize=sizeof(WNDCLASSEX);
    	HINSTANCE hinst=AfxGetInstanceHandle();
    	if(CView::PreCreateWindow(cs)&&cs.lpszClass!=NULL)
    	{
    		HBRUSH hbkbrush=CreateSolidBrush(RGB(0,0,0));
    		if(!GetClassInfoEx(hinst,cs.lpszClass,&wndcls))
    			return FALSE;
    		UnregisterClass(cs.lpszClass,hinst);
    		wndcls.hbrBackground=hbkbrush;
    		RegisterClassEx(&wndcls);  
    		return TRUE;
    	}
    	else
    		return FALSE;
    	return CView::PreCreateWindow(cs);
    }
    
    /
    // CDataHideInBMPView drawing
    
    void CDataHideInBMPView::OnDraw(CDC* pDC)
    {
    	CDataHideInBMPDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	// TODO: add draw code for native data here
    	RECT Rect;
    	GetClientRect( &Rect );
    
    	if (!show_contrast)
    		m_BMPHider.Draw( pDC, 0, 0, Rect.right, Rect.bottom, ImageStyle );
    	else
    	{
    		m_BMPHider.DrawContrast(pDC, Rect.right, Rect.bottom);
    		pDC->SetBkColor((0,0,0));
    		pDC->SetTextColor((255,255,255));
    		pDC->TextOut(0, Rect.bottom-30, "左图为原始图,右图为嵌入了隐藏信息的图");
    	}
    }
    
    /
    // CDataHideInBMPView printing
    
    BOOL CDataHideInBMPView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    	// default preparation
    	return DoPreparePrinting(pInfo);
    }
    
    void CDataHideInBMPView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    	// TODO: add extra initialization before printing
    }
    
    void CDataHideInBMPView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    	// TODO: add cleanup after printing
    }
    
    /
    // CDataHideInBMPView diagnostics
    
    #ifdef _DEBUG
    void CDataHideInBMPView::AssertValid() const
    {
    	CView::AssertValid();
    }
    
    void CDataHideInBMPView::Dump(CDumpContext& dc) const
    {
    	CView::Dump(dc);
    }
    
    CDataHideInBMPDoc* CDataHideInBMPView::GetDocument() // non-debug version is inline
    {
    	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDataHideInBMPDoc)));
    	return (CDataHideInBMPDoc*)m_pDocument;
    }
    #endif //_DEBUG
    
    /
    // CDataHideInBMPView message handlers
    
    void CDataHideInBMPView::OnNormal() 
    {
    	// TODO: Add your command handler code here
    	ImageStyle = 0;
    
    	CMenu *pMnu = AfxGetMainWnd()->GetMenu( );
    	pMnu->CheckMenuItem(ID_STRETCH,MF_UNCHECKED);
    	pMnu->CheckMenuItem(ID_NORMAL,MF_CHECKED);
    	
    	InvalidateRect( NULL, TRUE );
    	UpdateWindow();	
    }
    
    void CDataHideInBMPView::OnStretch() 
    {
    	// TODO: Add your command handler code here
    	ImageStyle = 1;
    	
    	CMenu *pMnu = AfxGetMainWnd()->GetMenu( );
    	pMnu->CheckMenuItem(ID_STRETCH,MF_CHECKED);
    	pMnu->CheckMenuItem(ID_NORMAL,MF_UNCHECKED);
    	
    	InvalidateRect( NULL, TRUE );
    	UpdateWindow();	
    }
    
    void CDataHideInBMPView::OnFileOpen() 
    {
    	// TODO: Add your command handler code here
    	show_contrast = false;   //非对比显示
    	static char szFilter[] = "BMP Files(*.BMP)|*.BMP||";
    
    	CFileDialog FileDlg( TRUE, NULL, NULL,
    		OFN_HIDEREADONLY, szFilter );
    
    	if( FileDlg.DoModal() == IDOK &&
    		m_BMPHider.Load( FileDlg.GetPathName() ) )
    	{
    		InvalidateRect( NULL, TRUE );
    		UpdateWindow();
    		have_open_a_file=true;
    		if (m_BMPHider.tag == 0)//该图无隐藏信息
    		{
    			embed = true;
    			pick = false;  //菜单亮暗控制
    		}//
    		else
    		{
    			embed = false;
    			pick = true;  //菜单亮暗控制
    		}//
    	}	
    }
    
    void CDataHideInBMPView::OnEmbed() 
    {
    	// TODO: Add your command handler code here
    	//弹出打开对话框,用户选择嵌入的文件
    
    	static char szFilter[] = "All Files(*.*)|*.*||";
    
    	CFileDialog FileDlg( TRUE, NULL, NULL,
    		OFN_HIDEREADONLY, szFilter );
    
    	if( FileDlg.DoModal() == IDOK &&
    		m_BMPHider.LoadEmbFile( FileDlg.GetPathName() ) )
    	{ 
    		if (m_BMPHider.bitmap_size / m_BMPHider.embfile_size < 8)
    		{
    			AfxMessageBox("文件太大,无法嵌入!");
    		}
    		else
    		{
    			show_contrast = true;
    			m_BMPHider.BackUpDib(); //图片原始数据备份供对比显示
    			m_BMPHider.Embed();   //嵌入
    			
    			Invalidate(true);//刷屏,显示加入隐藏信息后的图像
    			
    			static char szFilter[] = "BMP Files(*.BMP)|*.BMP||";
    			CFileDialog FileDlg( FALSE, "bmp", NULL,                //保存
    				OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter );
    			
    			if( FileDlg.DoModal() == IDOK )
    			{
    				m_BMPHider.Save( FileDlg.GetPathName() );
    			}
    			embed = false;
    		}
    		
    	}	
    }
    
    void CDataHideInBMPView::OnUpdateEmbed(CCmdUI* pCmdUI) 
    {
    	// TODO: Add your command update UI handler code here
    	pCmdUI->Enable(embed);	
    }
    
    void CDataHideInBMPView::OnPick() 
    {
    	// TODO: Add your command handler code here
    	//提取完毕,弹出保存对话框,用户进行保存
    	static char szFilter[] = "All Files(*.*)|*.*||";
    	CFileDialog FileDlg( FALSE, "", NULL,                //保存
    		OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter );
    				
    	if (FileDlg.DoModal() == IDOK)
    	{	
    		m_BMPHider.Pick();
    		m_BMPHider.SavePicked(FileDlg.GetPathName());
    		pick = false;
    	}	
    }
    
    void CDataHideInBMPView::OnUpdatePick(CCmdUI* pCmdUI) 
    {
    	// TODO: Add your command update UI handler code here
    	pCmdUI->Enable(pick);	
    }
    


     

    展开全文
  • 走进信息隐藏的世界,全面讲解信息隐藏——第1节:信息隐藏技术简介 专栏题记:奥斯卡优秀电影《美丽心灵》里面有讲述一位优秀数学家为政府破译敌国通讯的情节,如电影所讲,现实中也有着类似的情节,在我们的生活...

    走进信息隐藏的世界,全面讲解信息隐藏——第1节:信息隐藏技术简介


    专栏题记:奥斯卡优秀电影《美丽心灵》里面有讲述一位优秀数学家为政府破译敌国通讯的情节,如电影所讲,现实中也有着类似的情节,在我们的生活中,我们所看过的图片、视频和游览过的网页,也许就隐藏着他人需要传输的秘密信息(是不是有点恐怖,差一点成为帮凶了),这就是信息隐藏!由于应用场景一般比较神秘,导致很多人其实都不太了解信息隐藏技术。由于国家越来越重视网络信息的安全,现在也是有越来越多的研究人员进行着这方面的研究工作。本人也是其中一位非常平凡的研究人员,笔者抱着学习和分享的态度,希望略尽绵薄之力让大家对信息隐藏技术不再陌生,同时慢慢掌握如何进行信息隐藏的技术。接下来本人会不定时更新信息隐藏技术的相关原理和关键技术实现过程,同时会提供程序代码给大家学习,也欢迎有志之士可以和我一同创建学习平台,也可以在评论下建议下一节希望学习的研究内容。谢谢!


    目录

    1、信息隐藏概念

    2、信息隐藏系统模型

    3、信息隐藏技术的分支简介

    4、信息隐藏技术的特性和要求

    5、信息隐藏关键技术

    6、信息隐藏的应用实例

    案例一:信息隐藏技术在电子商务中的应用

    案例二:信息隐藏技术在网络战中的运用



    • 信息隐藏概念

           信息隐藏也称数据隐藏,信息隐藏技术是指在不对载体数据产生可察觉影响的前提下,将密信数据隐藏到载体中实现隐蔽通讯的技术。是集多学科理论与技术于一身的新兴技术领域。信息隐藏技术主要是指将特定的信息嵌入数字化宿主信息(如文本,数字化的声音、图像、视频信号等)中,信息隐藏的目的不在于限制正常的信息存取和访问,而在于保证隐藏的信息不引起监控者的注意和重视,从而减少被攻击的可能性,在此基础上再使用密码术来加强隐藏信息的安全性,因此信息隐藏比信息加密更为安全。应该注意到,密码术和信息隐藏技术不是互相矛盾、互相竞争的技术,而是相互补充的技术,他们的区别在于应用的场合不同,对算法的要求不同,但可能在实际应用中需要互相配合。特定的信息一般就是保密信息,信息隐藏的历史可以追溯到古老的隐写术,但推动了信息隐藏的理论和技术研究始于1996年在剑桥大学召开的国际第一届信息隐藏研究会,之后国际机构在信息隐藏领域中的隐写术、数字水印、版权标识,可视密码学等方面取得大量成果。


    • 信息隐藏系统模型

           广义的信息隐藏系统模型主要有四部分组成:(1)信息嵌入,即利用嵌入秘钥来实现嵌入对象的隐藏过程;(2)信息提取,即利用提取秘钥从隐藏对象或可能经过修改的隐藏对象中提取或恢复出嵌入对象,在提取时,原始的载体对象可能需要参与也可能不需要参与;(3)秘钥生成,根据安全参数生成嵌入秘钥和提取秘钥;(4)隐藏分析,隐藏对象在传输过程中可能会被隐藏分析者截获并进行处理。信息隐藏系统模型如下图所示:

           在信息隐藏系统模型中,在嵌入过程中我们使用嵌入密钥将嵌入对象嵌入掩护对象中,生成隐藏对象,如下图将一个txt的文本嵌入到一张JPEG的图像中。嵌入对象和掩护对象可以是文本、图像或音频等等。在我们没有使用工具进行分析时,我们觉得掩护对象与隐藏对象几乎没有差别,这就是信息隐藏概念中所说的“利用人类感觉器官的不敏感性”。隐藏对象在信道中进行传输,在传输的过程中,有可能会遭到隐藏分析者的攻击,隐藏分析者的目标在于检测出隐藏对象、查明被嵌入对象、向第三方证明消息被嵌入、删除被嵌入对象、阻拦等。其中前三个目标通常可以由被动观察完成,称为被动攻击,后两个目标通常可以由主动攻击实现。提取过程则是在提取密钥的参与下从所接收到的隐藏对象中提取出嵌入对象,如将上述txt文件从JPG的图像中提取出来。有些提取过程并不需要掩护对象的参与,这样的系统称为盲隐藏技术,而需要掩护对象参与的系统则称为非盲隐藏技术。


    • 信息隐藏技术的分支简介

           作为信息安全领域的一个重要组成部分,信息隐藏技术已成为信息安全领域中一个既具有研究价值、同时又极具挑战性的热门课题,信息隐藏技术的分支主要包括:隐写术、数字水印、数字指纹、隐蔽信道、阈下信道、低截获概率通信和匿名通信等等。其分类示意图如下图所示:


    • 信息隐藏技术的特性和要求

           信息隐藏不同于传统的加密,因为其目的不在于限制正常的资料存取,而在于保证隐藏数据不被发现。因此,信息隐藏技术必须考虑正常的信息操作所造成的威胁,即要使机密数据对正常的数据操作技术具有免疫力。根据信息隐藏的不同目的和技术要求,该技术的存在以下特性和要求:

    1. 透明性或不可感知性:利用人类视觉系统或人类听觉系统属性,经过一系列的隐藏处理,使得载体对象没有明显的降质现象,如LSB算法等。当然,有些场合可能需要使用可见水印,例如某些版权维护的场合。
    2. 鲁棒性:指不因隐藏对象通过某些常用操作而导致嵌入对象丢失的能力。这里的常用操作包括滤波操作、有损压缩、几何变换、D/A或A/D等。
    3. 安全性:指算法具有较强的抗恶意攻击能力。
    4. 不可检测性:指载体数据嵌入数据后无明显改变,至少肉眼看不出变化

    • 信息隐藏关键技术

      近年来,信息隐藏技术的研究取得了很大的进步,已经提出了各种各样的隐藏算法。关键的信息隐藏技术有如下几种。

        (1)替换技术

        所谓替换技术,就是试图用秘密信息比特替换掉伪装载体中不重要的部分,以达到对秘密信息进行编码的目的。替换技术包括最低比特位替换、伪随机替换、载体区域的奇偶校验位替换和基于调色板的图像替换等。替换技术是在空间域进行的一种操作,通过选择合适的伪装载体和适当的嵌入区域,能够有效地嵌入秘密信息比特,同时又可保证数据的失真度在人的视觉允许范围内。

        已经提出的各种算法大都给出了其实现思想,如对于基于调色板的图像格式,可操作其调色板来嵌入信息,也可以利用它的量化值来隐藏秘密信息,因此该技术在数据伪装中得到了广泛的应用。

        替换技术算法简单,容易实现,但是鲁棒性很差,不能抵抗图像尺寸变化、压缩等一些基本的攻击,因此在数字水印领域中一般很少使用。

        (2)变换技术

        大部分信息隐藏算法都是在变换域进行的,其变换技术包括离散傅里叶变换(DFT)、离散余弦变换(DFT)、离散小波变换(DWT)和离散哈达玛特变换(DHT)等。这些变换技术都有各自的特点。

        DFT在信号处理中有着广泛应用,在信息隐藏领域也同样得到了应用。它将图像分割成多个感觉频段,然后选择合适部分来嵌入秘密信息。D CT使空间域的能量重新分布,从而降低了图像的相关性。在DCT域中嵌入信息的方法,通常是在一个图像块中调整两个(或多个)DCT系数的相对大小。DWT是对图像的一种多尺度、空间频率分解,即将输入信号分解为低分辨率参考信号和一系列细节信号。在一个尺度下,参考信号和细节信号包含了完全恢复上一尺度下信号的全部信息。

        (3)扩频技术

        当对伪装对象进行过滤操作时可能会消除秘密信息,解决的方法就是重复编码,即扩展隐藏信息。在整个伪装载体中多次嵌入一个比特,使得隐藏信息在过滤后仍能保留下来,这种方法虽然传输效率不高,但却具有较好的健壮性。扩频技术一般是使用比发送的信息数据速率高许多倍的伪随机码,将载有信息数据的基带信号频谱进行扩展,形成宽带低功率谱密度信号。最典型的扩频技术,为直序扩频和跳频扩频。直序扩频是在发端直接用具有高码率的扩频编码去扩展信号的频谱,而在接收端用相同的扩频编码解扩,将扩频信号还原为原始信号。跳频扩频是在发端将信息码序列与扩频码序列组合,然后按照不同的码字去控制频率合成器,使输出频率根据码字的改变而改变,形成频率的跳变;在接收端为了解跳频信号,要用与发端完全相同的本地扩频码发生器去控制本地频率合成器,从中恢复出原始信息


    • 信息隐藏的应用实例

    案例一:信息隐藏技术在电子商务中的应用

      目前信息隐藏技术在电子商务中的应用主要体现在以下几个方面:

      1.数据保密

      在具体电子商务活动中,数据在Internet上进行传输一定要防止非授权用户截获并使用,如敏感信息,谈判双方的秘密协议合同网上银行交易中的敏感数据信息,重要文件的数字签名和个人隐私等等。另外,还可以对一些不愿为别人所知道的内容使用信息隐藏的方式进行隐藏存储。

      2.数据的不可抵赖性

      在网上交易中,交易双方的任何一方不能抵赖自己曾经做出的行为,也不能否认曾经接收到的对方的信息,这是交易系统中的一个重要环节。这可以使用信息隐藏技术中的水印技术,在交易体系的任何一方发送或接收信息时,将各自的特征标记以水印的形式加入到传递的信息中,这咱水印应是不能被去除的,可达到确认其行为的目的。

      3.防伪

      商务活动中的各种票据的防伪也是信息隐藏技术的用武之地。在数字票据中隐藏的水印经过打印后仍然存在,可以通过再扫描回数字形式,提取防伪水印,以证实票据的真实性。

      4.数据的完整性

      对于数据完整性的验证是要确认数据在网上传输或存储过程中并没有被窜改,可通过使用脆弱水印技术保护的媒体一旦被窜改就会破坏水印,从而很容易被识别。

    案例二:信息隐藏技术在网络战中的运用[2]

      信息隐藏之所以比密码加密的方法进行保密通信具有更大优势,是因为以信息隐藏方式实现隐蔽通信,除通信双方以外的任何第三方并不知道秘密通信这个事实的存在,这就较之单纯的密码加密更多了一层保护,使得网络加密机制从“看不懂”变为“看不见”,以不至成为好事者攻击的目标。

      (1)数据保密

      在因特网上防止非授权用户截获并使用传输的一些秘密数据,是网络安全的一个重要内容。信息隐藏技术在军事上的应用,可以将一些不愿为人所知的重要标识信息用信息隐藏的方式进行隐蔽存储,像军事地图中标明的军备部署、打击目标,卫星遥感图像的拍摄日期、经纬度等等,都可用隐藏标记的方法使其以不可见的形式隐藏起来,只有掌握识别软件的人才能读出标记所在。

      (2)数据保护

      数据保护主要是保证传输信息的完整性。由于隐藏的信息是被藏在宿主图像等媒体的内容中,而不是文件头等处,因而不会因格式的变换而遭到破坏。同时隐藏的信息具有很强的对抗非法探测和非法破解的能力,可以对数据起到安全保护的作用。对于数据完整性的验证是要确认数据在网上传输或存储过程中并没有被窜改。通过使用脆弱水印技术保护的媒体一旦被窜改就会破坏水印,从而很容易被识别。

      (3)数据免疫

      所谓免疫是指不因宿主文件经历了某些变化或处理而导致隐藏信息丢失的能力。某些变化和处理包括:传输过程中的信道噪声干扰,过滤操作,再取样,再量化,数/模、模/数转换,无损、有损压缩,剪切,位移等。


    作者:Daniel
    来源:CSDN 
    版权声明:本文为原创文章,转载请附上博文链接:
    https://blog.csdn.net/qq_26464039/article/details/85779870


    展开全文
  • 在整个介绍信息隐秘技术部分, 为了统一起见, 我们约定以下名词: 称需要隐秘的信息为秘密信息( secret) , 秘密信息隐藏的媒介叫做载体( cover) , 隐藏后的结果叫做隐蔽载体( stego-cover) 一、图...

    从本章开始, 我们将具体接触到许多数字信息的隐写术。为了与后面数字水印技术相区别, 我们也将隐写术称为信息隐秘技术。本章主要阐述图像信息作为秘密信息的隐藏, 即图像降级隐写。
    在整个介绍信息隐秘技术部分, 为了统一起见, 我们约定以下名词: 称需要隐秘的信息为秘密信息( secret) , 秘密信息隐藏的媒介叫做载体( cover) , 隐藏后的结果叫做隐蔽载体( stego-cover)
    一、图像降级
    主体对客体的读写一般应满足以下两个规则:
    规则 1: 主体只能向下读, 不能向上读。
    规则 2: 主体只能向上写, 不能向下写。
    我们通常所说的信息降级, 就是通过将秘密信息嵌入较低安全级别的客体中, 破坏了第二个规则, 从而使机密的信息看上去不再机密。在伪装技术中我们经常要这样做, 以使秘密信息被伪装成为低级别的信息, 不易被发现。图像降级就是伪装技术的一个应用。
    二、简单的图像信息伪装技术
    1.直接 4bit 替换法
    这是将秘密图像信息嵌入载体图像的一种最简单的方法,指直接用秘密图像像素值的高 4bit 去替换载体图像像素值的低 4bit。

    % 文件名: imagehide. m
    % 函数功能: 直接将秘密图像的高 4bit 隐藏在 RGB 载体图像的 R, G, B 层中所
    选的那一层的低 4bit, 并将秘密图像提取出来, 最后显示。要求载体图像的大小大于
    等于秘密图像的大小, 且秘密图像是二值或灰度图像
    % 输入格式:
    % data = imagehide( ′c: \ lenna. bmp′, ′c: \ woman. bmp′, ′c: \mix. bmp′, ′bmp′, 3 )
    % 参数说明
    % cover 是载体图像的地址
    % message 是秘密图像的地址
    % goleimage 是隐藏后图像的地址
    % permission 是图像的类型
    % level 是作为载体的具体层, R 为 1 , G 为 2, B 为 3
    % data 是隐藏后图像的矩阵
    
    function data = imagehide( cover, message, goleimage, permission, level)
    % 提取图像信息并分层
    cover = imread( cover, permission) ;
    data = cover;
    msg = imread( message, permission) ;
    [ row, col] = size( cover) ;
    cover1 = cover(∶,∶, level) ;
    % 置载体图像 R 层的低 4bit 为 0
    for i = 1∶row
    		for j = 1∶col /3
    				cover1( i, j) = bitand( cover1( i, j) , 240) ;
    		end
    end
    % 置秘密图像的低 4bit 为 0
    takemsg4 = bitand( msg, 240) ;
    % 将秘密图像的高 4bit 右移 4 位
    shiftmsg4 = bitshift( takemsg4, - 4) ;
    % 图像隐藏
    for i = 1∶row
    		for j = 1∶col /3
    				cover1( i, j) = bitor( cover1( i, j) , shiftmsg4( i, j) ) ;
    		end
    end
    % 写回并保存
    data(∶,∶, level) = cover1;
    imwrite( data, goleimage, permission) ;
    % 提取秘密图像信息, 检测隐藏效果
    data = imread( goleimage, permission) ;
    [ row, col] = size( data) ;
    A = data(∶,∶, level) ;
    for i = 1∶row
           for j = 1∶col /3
    				A( i, j) = bitand( A( i, j) , 15) ;
           end
    end
    A = bitshift( A, 4) ;
    % 显示结果
    subplot( 221) , imshow( cover) ; title( ′载体图像′) ;
    subplot( 222) , imshow( message) ; title( ′秘密图像′) ;
    subplot( 223) , imshow( data) ; title( ′隐藏后的图像′) ;
    subplot( 224) , imshow( A) ; title( ′提取的秘密图像′) ;
    

    但无论选择R G B三层中的哪层嵌入,都会在不同程度上对原始图像造成破坏
    考虑到第一章中我们阐述的 RGB 颜色模型, 将秘密图像隐藏在一层中, 容易导致该点的色彩向相应的坐标上发生绝对偏移, 从而使得该像素点的色彩的相应分量突出。所以, 我们不能笼统地认为图像隐藏在某层比较好而隐藏在某层不好, 这是因为对于具体的某个像素点其哪个颜色分量突出是不确定的。但是, 我们可以通过改进算法来限制这种颜色沿相应坐标的绝对偏移。

    例如, 可将秘密图像像素值的高 4bit 分别藏于载体图像 R, G, B 层像素值的最低位或次低位, 即将秘密图像的高 2bit 藏于 R 层, 另外 2bit 分别藏于 G 层和 B 层, 此时像素色彩的改变就不是沿一个坐标方向而改变, 而是在整个 RGB 空间中发生偏移, 改变后的颜色坐标点与改变前的颜色坐标点的距离( 数学上的范数) 比单纯在一个分量上改变的两点距离要小, 这样对载体图像的影响会更小。在实际应用中, 还应该考虑隐藏的鲁棒性等问题。

    2.对第 4bit 的考察
    可以发现,直接替换 4 bit 后, 图像还是有一些变化的, 也就是说, 替换容量大使图像的保真度降低( 可通过实验看到替换 3bit 的效果比替换 4bit 的效果要好)
    在这种情况下,我们可以用秘密信息图像像素值的高3bit去替换载体图像像素值的低3bit,至于第 4bit 则要具体分析
    其假设前提是: 如果只对图像进行 3bit 替换, 是不会对图像的视觉效果造成影响的。事实上, 这种假设是可以成立的

    首先, 我们引入一个相似度的概念, 所谓相似度, 是指两图像块中同一坐标下的像素中第 4bit 相同的像素数量占一块图像全部像素的比例, 表示为:μ=s/64
    其中 s 为第 4bit 相同的像素数量 64 为 8× 8 块中的总像素数
    根据 μ的取值我们来确定该块各像素第 4bit 的隐藏策略。
    我们先计算相应块的载体图像与秘密图像在第 4bit 的相似度 μ, 如果 μ大于某一阈值 T, 则可直接用秘密图像的第 4 bit 替换载体图像的第 4bit, 如果 μ小于阈值1 - T, 则先将秘密图像的第 4bit 取反后再替换, 若 μ介于 1 - T 和 T 之间, 则不进行替换。当然, 要用一个替换表对第 4bit 进行替换或取反替换了的块进行记录, 并且将此表也嵌入到载体图像中。编写函数 fourthbitcmp. m 完成记录替换表的实验, 函数代码如下:

    % 文件名: fourthbitcmp. m
    % 函数功能: 计算秘密图像和选择的载体图像层, 对于第 4bit 的每一个 8× 8 块,哪些可以用秘密图像去替换载体图像, 并返回一个替换表 count, 要求两个图像都可以整数 8× 8 分块
    % 输入格式: count = fourthbitcmp( ′c: \lenna. bmp′, ′c: \woman. bmp′, ′bmp′, 3, 0. 7)
    % 参数说明:
    % cover 是载体图像的地址
    % message 是秘密图像的地址
    % permission 是图像的类型
    % level 是作为载体的具体层。R 为 1, G 为 2 , B 为 3
    % count 是替换表
    % threshold 是阈值
    function count = fourthbitcmp( cover, message, permission, level, threshold)
    % 提取图像信息并分层
    cover = imread( cover, permission) ;
    data = cover;
    msg = imread( message, permission) ;
    cover1 = cover(∶,∶, level) ;
    % 对 cover 和 msg 的第 4bit 进行处理
    tempc = cover1;
    tempm = msg;
    tempc = bitand( tempc, 8) ;
    tempm = bitand( tempm, 8) ;
    temp = bitxor( tempm, tempc) ;
    [ row, col] = size( temp) ;
    % 记录图像每个分块的 n 值
    k1 = 0;
    k2 = 0;
    a = row* col /64;
    count = zeros( [ 1 a] ) ;
    for i = 1∶a
    	for m = 1∶8
    		for n = 1∶8
    				if temp( 8* k1 + m, 8* k2 + n) == 0
    					count( 1, i) = count( 1, i) + 1;
    				end
    		end
    	end
    	k2 = k2 + 1;
    	if k2* 8 == col
    			k2 = 0;
    					k1 = k1 + 1;
    			end
    	end
    % 计算每块的 μ值并与阈值进行比较
    count = count /64;
    for i = 1∶a
    	if count( i) >= threshold
    		count( i) = 1; % 可以替换
    			elseif count( i) < 1 - threshold
    				count( i) = - 1; % 取反
    			else
    		        count( i) = 0; % 不能处理
    	end
    end
    

    依据本算法, 在同一阈值下经不同层计算出的替换表中 0 的个数, 个数越少的层越适宜当做载体。当然, 为了简单起见, 也可以不加分块直接计算秘密图像与载体图像 R、G、B 层中哪一层的相似度高, 就选择哪一层为载体。
    三、图像置乱
    置乱实际上就是图像的加密, 与加密保证安全性不同的是, 将置乱的图像作为秘密信息再进行隐藏, 可以很大限度地提高隐蔽载体的鲁棒性, 所以图像置乱是信息隐藏中常用的一项技术。
    1、变化模板形状的图像置乱算法
    变化模板形状的图像置乱算法的思想如下:
    ① 对原图像取一个固定模板, 模板中像素位置排列如图 4. 10 所示。
    ② 做一个与原图像模板不同的置乱模板, 如图 4. 11 所示, 在置乱模板中把图像模板中的像素位置按一定次序填入
    ③ 将置乱模板中的像素位置再按一定的次序填回到原图像模板中就得到了置乱后的图像模板( 图 4. 12 的模板是按从左到右、从上到下的次序依次读取置乱模板中像素位置) 。
    在这里插入图片描述
    可以发现, 这种置乱算法是对合的
    与前面 Zigzag 变换一样, 我们也采取查表的方法编写程序。由于我们固定了置乱模板的大小, 所以在对图像置乱前我们要对其进行边界修补。如取置乱模板为 32× 32, 则要求秘密图像的尺寸为 32× 32,64× 64 , 128× 128, …。假设一幅图像的尺寸为 32× 31 , 则应该对其增加 1 列数据。
    变换表分为行表和列表, 同一坐标下的行列表中的数据结合起来所指示的像素将被置乱到这一坐标下。
    此外, 在图像置乱机制中引入一个简单的密钥控制。将由密钥生成的第一个[ 128, 255] 的随机整数与置乱的结果进行模 2 加。编写程序 diamondreplace. m 完成置乱实验。其中需要调用查表程序 replace32 fun. m, 函数代码如下:
    ( 1 ) 主函数: diamondreplace. m

    % 文件名: diamondreplace. m
    % 函数功能: 本函数将完成对输入的图像信号按菱形置换策略进行置乱
    % 输入格式举例: result = diamondreplace( secretimage, 1983 )
    % 参数说明:
    % matrix 为输入图像矩阵
    % key 为控制密钥
    % result 为置乱后的结果
    function result = diamondreplace( matrix, key)
    % 分析原图像尺寸并补遗
    [ m, n] = size( matrix) ;
    rowadd = 32-mod( m, 32) ;
    coladd = 32-mod( n, 32 ) ;
    if rowadd== 32
    rowadd = 0;
    end
    if coladd== 32
    coladd = 0;
    end
    input = uint8( zeros( [ m + rowadd n + coladd] ) ) ;
    input( 1∶m, 1∶n) = matrix;
    % 密钥生成随机数
    rand( ′seed′, key) ;
    control = randint( 1, 1 , [ 128 255] ) ;
    % 查表置乱
    fun = @replace32fun; % 调用子函数
    result = blkproc( input, [ 32 32] , fun) ;
    result = bitxor( result, control( 1 , 1) ) ;
    

    ( 2 ) 查表函数: replace32fun. m

    function result = replace32fun( matrix)
    % 行转换表
    row = [ 16 15 17 14 16 18 …] % 此处略去, 具体内容请见表 4. 3
    col = [ 17 18 17 20 18 16 …] % 此处略去, 具体内容请见表 4 . 4
    for i = 1∶32
    for j = 1∶32
    result( i, j) = matrix( row( i, j) , col( i, j) ) ;
    end
    end
    

    woman图像置乱后的效果
    将图像的原始信息破坏得越大越好, 不过, 这种破坏一定要是可以复原的

    2.图像的幻方变换

    % 文件名: magicsquares. m
    % 函数功能: 本函数将完成 n 阶二维幻方的求取 . 要求 n 为奇数
    % 输入格式举例: result = magicsquares( 5)
    % 参数说明:
    % n 为阶数
    % result 为求得的二维幻方
    function result = magicsquares( n)
    if mod( n, 2) == 0
    error( ′n 要求为奇数′) ;
    end
    result = zeros( n) ;
    j = floor( n /2 ) + 1; % 中间 1 列
    i = n + 1; % 便于以后从第 n 行开始考虑起
    result( 1, j) = 1 ;
    for k = 2∶n* n % 依次考虑后 n^2 - 1 个数
    i = i - 1 ;
    j = j + 1 ; % 行数减 1, 列数加 1
    if i < 1 && j > n % 特殊情况 4
    i = i + 2 ;
    j = j - 1 ;
    else
    if i < 1 % 特殊情况 1
    i = n;
    end
    if j > n % 特殊情况 2
    j = 1;
    end;
    end;
    if result( i, j) == 0
    result( i, j) = k;
    else % 特殊情况 3
    i = i + 2 ;
    j = j - 1 ;
    result( i, j) = k;
    end
    end
    
    

    我们知道, 要图像置乱是为了增加隐藏的鲁棒性。一个置乱的图像无论是合法用户还是非法用户都看不懂, 要使合法用户能完整地读取秘密信息, 就要满足两个条件:
    ①仅有合法用户知道的密钥参与运算。
    ②置乱算法本身可以保证图像复原, 即算法是可逆的。
    幻方置乱的思想其实也是查表思想,其运算具有准对合性,具体算法实现后面再阐述
    编 写 函 数 magicreplace. m 完 成 置 乱 实 验, 其 中 需 要 调 用 查 表 函 数replacemagicfun. m。前主函数存放 11 阶标准幻方, 子函数存放表 4. 6 , 函数代码如下:
    ( 1 ) 幻方置乱主函数: magicreplace.m

    % 文件名: magicreplace. m
    % 函数功能: 本函数将完成对输入的图像信号按幻方置换策略进行置乱
    % 输入格式举例: result = magicreplace( secretimage, 1, 1983)
    % 参数说明:
    % matrix 为输入图像矩阵
    % key 为控制密钥
    % eord 为 1 表示置乱变换, 为 0 表示复原变换
    % result 为置乱后的结果
    function result = magicreplace( matrix, eord, key)
    % 分析原图像尺寸并补遗
    [ m, n] = size( matrix) ;
    rowadd = 11-mod( m, 11) ;
    coladd = 11-mod( n, 11 ) ;
    if rowadd == 11
    rowadd = 0;
    end
    if coladd == 11
    coladd = 0;
    end
    input = uint8( zeros( [ m + rowadd n + coladd] ) ) ;
    input( 1∶m, 1∶n) = matrix;
    % 密钥生成随机数
    rand( ′seed′, key) ;
    control = randint( 1, 1 , [ 1 121] ) ;
    % 11 阶标准幻方
    magic =
    [ 38 52 66 69 83 97 100 114 7 21 24 
      61 75 78 92 106 120 2 16 30 44 47
      84 98 101 115 8 22 25 39 53 56 70 
      107 121 3 17 31 34 48 62 76 79 93 
      9 12 26 40 54 57 71 85 99 102 116
      32 35 49 63 77 80 94 108 111 4 18 
      55 58 72 86 89 103 117 10 13 27 41
      67 81 95 109 112 5 19 33 36 50 64
      90 104 118 11 14 28 42 45 59 73 87
      113 6 20 23 37 51 65 68 82 96 110 
      15 29 43 46 60 74 88 91 105 119 1 ] ; 
    if eord == 0
    control = 121 -control;
    elseif eord == 1
    control = control;
    else
    error( ′输入参数错误′) ;
    end
    % 幻方变换主过程
    for define = 1∶key% control
    	for r = 1∶11
    		for c = 1∶11
    			magic( r, c) = magic( r, c) -1;
    			if magic( r, c) == 0
    					magic( r, c) = 121;
    			end
    		end
    	end
    end
    % 查表置乱
    fun = @replacemagicfun; % 调用子函数
    result = blkproc( input, [ 11 11] , fun, magic) ;
    

    ( 2 ) 行列转换表子函数: replacemagicfun. m

    % 11 阶幻方的行列查找表程序
    function result = replacemagicfun( matrix, P1 )
    % 初始化 11 阶幻方的行列查找表
    row = [ 11 , 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 5, 7, 9, 11, 2, 4, 6 , 8, 10, 1 , 3, 10, 1 , 3, 5, 7, 9,
    11, 2, 4, 6 , 8, 4, 6, 8, 10, 1, 3, 5, 7, 9 , 11, 2 , 9 , 11, 2, 4, 6, 8 , 10, 1, 3, 5 , 7, 3, 5, 7 , 9, 11 , 2,
    4 , 6 , 8, 10 , 1, 8, 10 , 1, 3, 5, 7, 9, 11, 2, 4, 6 , 2 , 4 , 6, 8, 10, 1 , 3, 5, 7, 9, 11, 7, 9, 11, 2, 4 , 6,
    8 , 10, 1, 3 , 5, 1, 3, 5, 7, 9, 11, 2, 4, 6 , 8, 10 , 6 , 8, 10 , 1, 3, 5, 7, 9, 11, 3, 4] ;
    col = [ 11, 7, 3, 10, 6, 2, 9, 5, 1, 8, 4 , 2, 9, 5, 1, 8, 4, 11, 7, 3 , 10, 6, 4, 11, 7 , 3, 10 , 6,
    2 , 9 , 5, 1, 8, 6, 2, 9, 5 , 1, 8, 4, 11, 7, 3, 10 , 8, 4, 11, 7 , 3, 10, 6, 2, 9, 5 , 1, 10, 6, 2 , 9, 5, 1,
    8 , 4 , 11, 7 , 3, 1, 8, 4, 11, 7, 3, 10, 6, 2, 9, 5 , 3 , 10, 6, 2, 9, 5 , 1, 8, 4, 11 , 7, 5, 1, 8 , 4, 11 , 7,
    3 , 10, 6, 2 , 9, 7, 3, 10, 6, 2, 9, 5, 1, 8 , 4, 11 , 9 , 5, 1, 8, 4, 11, 7, 3, 10, 6, 2] ;
    for i = 1: 11
    	for j = 1: 11
    		result( i, j) = matrix( row( P1 ( i, j) ) , col( P1( i, j) ) ) ;
    	end
    end
    

    3.图像的 Ha sh 置乱
    前面的两种置乱都是对图像分块进行的, 而且其共同的问题是密钥控制并不得力。下面介绍的一种图像置乱方法实际上就是我们在 2. 6. 3 节中介绍的 Hash 置换的特例———对于 m× n 个像素点, 我们要求随机置换 m× n 个, 就完成了图像的 Hash置乱。鉴于该算法具有无冲突( collision) 和强密钥控制的特点, 显然是一个很好的图像置乱算法。需要说明的是, 这种算法不是对合的, 所以在实现上较前两种复杂一些。另外, 其算法执行起来也比较费时间。编写函数 hashdisturb. m 完成实验

    % 文件名: hashdisturb. m
    % 函数功能: 本函数将完成对输入的图像信号按 Hash 置换策略进行置乱
    % 输入格式举例: result = hashdisturb( secretimage, 1, 1983 , 421, 1121)
    % 参数说明:
    % matrix 为输入图像矩阵
    % key1 -key3 为控制密钥
    % eord 为 1 表示置乱变换, 为 0 表示复原变换
    % result 为置乱后的结果
    function result = hashdisturb( matrix, eord, key1, key2, key3 )
    % 分析原图像尺寸并补遗
    [ m, n] = size( matrix) ;
    % 调用随机置换函数
    [ row, col] = hashreplacement( matrix, m* n, key1, key2, key3) ;
    % 置乱函数
    count = 1;
    if eord == 1
    	for i = 1∶m
    		for j = 1∶n
    			result( i, j) = matrix( row( count) , col( count) ) ;
    			count = count + 1;
    		end
    	end
    end
    % 复原函数
    if eord == 0
    	for i = 1∶m
    		for j = 1∶n
    			result( row( count) , col( count) ) = matrix( i, j) ;
    			count = count + 1;
    		end
    	end
    end
    
    

    4.隐藏置乱图像的优点
    置乱图像隐藏的抗恶意攻击性能
    经过多次置乱后, 图像就会彻底地改变, 从置乱后的图像上根本看不到原图像的任何特征。使用置乱方法为什么可以增加图像伪装的鲁棒性呢?
    首先, 将图像置乱后, 将得到一幅杂乱无章的图像, 这个图像无色彩、无纹理、无形状, 从中无法读取任何信息, 那么, 将这样一幅图嵌入到另一幅普通图像时就不易引起那幅图色彩、纹理、形状的太大改变, 甚至不会发生改变, 这样人眼就不易识别,从而逃出了第三方的视线。

    其次, 由于秘密图像是置乱后的图像, 根据上述图像的“三无”特征, 第三方根本不可能对其进行色彩、纹理、形状等的统计分析, 即便他们截取到了秘密图像, 也是无能为力的。如果第三者企图对秘密图像进行反置乱, 这也是不可能的, 由于图像置乱有很多种方法, 每种方法又可以使用不同的置乱模板算法, 设置不同的参数, 使用者有很大的自由度, 他可以根据自己的想法得到不同的结果, 相反, 这给企图截获秘密信息的第三方带来了很大的困难, 使他们需要耗费巨大的计算量来穷举测试各种可能性

    最后, 我们再设想一下, 如果第三方反置乱不成, 在隐蔽载体上恶意修改怎么办?通过实验我们知道, 用置乱的方法是可以抵抗这些攻击的, 因为对秘密图像进行反置换的过程, 就使得第三方在图像上所涂、画的信息分散到画面的各个地方, 形成了点状的随机噪声, 对视觉影响的程度不大。图 4. 20 是我们随意对隐蔽载体进行 3 种恶意攻击后提取的秘密图像内容。可以看到, 即使是在攻击 3 下, 秘密图像的轮廓依然可见, 这是在未置乱图像的隐藏下不可想像的。当然, 为了使提取的信息更为清晰,最好对破坏严重的图像进行边界保持的中值滤波等方面的处理, 以去除随机噪声。

    展开全文
  • 数据库安全性

    千次阅读 2012-12-28 20:44:36
    1.试述实现数据库安全性控制的常用方法和技术。  答:实现数据库安全性控制的常用方法和技术有:  1)用户标识和鉴别:该方法由系统提供一定的方式让用户标识自己的名字或身份。每次用户要求进入系统时,由系统...

    1.试述实现数据库安全性控制的常用方法和技术。

      答:实现数据库安全性控制的常用方法和技术有:

      1)用户标识和鉴别:该方法由系统提供一定的方式让用户标识自己的名字或身份。每次用户要求进入系统时,由系统进行核对,通过鉴定后才提供系统的使用权。

      2)存取控制:通过用户权限定义和合法权检查确保只有合法权限的用户访问数据库,所有未被授权的人员无法存取数据。例如C2级中的自主存取控制(DAC),B1级中的强制存取控制(MAC);

      3)视图机制:为不同的用户定义视图,通过视图机制把要保密的数据对无权存取的用户隐藏起来,从而自动地对数据提供一定程度的安全保护。

      4)审计:建立审计日志,把用户对数据库的所有操作自动记录下来放入审计日志中, DBA可以利用审计跟踪的信息,重现导致数据库现有状况的一系列事件,找出非法存取数据的人、时间和内容等。

      5)数据加密:对存储和传输的数据进行加密处理,从而使得不知道解密算法的人无法获知数据的内容。

        

    2.什么是数据库中的自主存取控制方法和强制存取控制方法?

      答: 自主存取控制方法:定义各个用户对不同数据对象的存取权限。当用户对数据库访问时首先检查用户的存取权限。防止不合法用户对数据库的存取。

      强制存取控制方法:每一个数据对象被(强制地)标以一定的密级,每一个用户也被(强制地)授予某一个级别的许可证。系统规定只有具有某一许可证级别的用户才能存取某一个密级的数据对象。

    3.什么是数据库的审计功能,为什么要提供审计功能?

      答:审计功能是指DBMS的审计模块在用户对数据库执行操作的同时把所有操作自动记录到系统的审计日志中。

      因为任何系统的安全保护措施都不是完美无缺的,蓄意盗窃破坏数据的人总可能存在。利用数据库的审计功能,DBA可以根据审计跟踪的信息,重现导致数据库现有状况的一系列事件,找出非法存取数据的人、时间和内容等。

    展开全文
  • Matlab-LSB信息隐藏实验

    万次阅读 多人点赞 2018-07-05 11:16:26
    一、实验内容实验完成形式: 用...能随机选择嵌入位进行信息隐藏及提取(考虑安全性因素) 3.能够计算PSNR,分析信息隐藏图像质量4.完成对秘密信息的图像载体进行攻击,采用的攻击方法: jpeg压缩,resize缩放 5....
  • 信息隐藏综述

    千次阅读 2020-04-22 15:49:13
    信息隐藏是把一个有意义的信息隐藏在另一个称为公开载体(Cover) 的信息中得到隐蔽载体 S(Stego Cover),非法者不知道这个普通信息中是否隐藏了其他的信息,而且即使知道也难以提取或去除隐藏信息。所用的载体可以...
  • 网络信息安全的重要

    万次阅读 2018-08-15 11:39:01
    一、信息安全技术概论 1.网络安全的重要作用 在互联网普及的初期,人们更关注单纯的连接...网络出现前:主要面向数据的安全,对信息的机密、完整和可用的保护,即CIA三元组;网络出现后,还涵盖了面向用...
  • 图片嵌入隐藏-大容量的信息隐藏算法

    万次阅读 热门讨论 2016-05-02 23:14:25
    且有实验表明在不影响图像视觉效果的前提下,其信息隐藏量比LSB算法大,并具有更高的安全性。该算法的主要思想是对每个像素点进行判断,根据HVS的特性,在最高非0有效位后的定位(y)开始嵌入隐藏信息,嵌入到另一个...
  • 利用MATLAB实现WAV音频的LSB信息隐藏

    千次阅读 2020-12-10 23:35:36
    近年来,虽然数字音频信息隐藏技术的研究工作发展很快,出现了一些代表算法,但是与图像信息隐藏算法相比,数字音频信息隐藏技术面临着更大的挑战,因为人类听觉系统对随机噪声十分敏感,使得可以嵌入的数据量非常...
  • 信息安全指保证信息的保密、完整、真实、占有。 占有要保护信息赖以存储的节点、介质、载体等不被盗用或窃取。方法有版权、专利、商业秘密等。 一、加密和解密 二、数字签名与数字水印 三、数字...
  • 信息隐藏技术综述——粗浅入门

    万次阅读 2018-03-12 14:50:50
    本文为2017年十一月做的关于信息隐藏技术的PPT汇报的配套讲稿,相关参考资料已上传至(http://download.csdn.net/download/sir_chai/10104787)第一页1996 年 5 月30 日,在英国的剑桥牛顿研究所召开了第一届国际...
  • 1.信息安全简介 勒索病毒----2013年9月CryptoLocker “永恒之蓝”:主要是利用Windows系统的共享漏洞:445端口等。 “永恒之蓝”传播的勒索病毒以ONION和WNCRY两个家族为主,受 害机器的磁盘文件会被篡改为相应...
  • 信息隐藏技术综述

    千次阅读 2007-03-01 19:58:00
    信息隐藏技术综述蔡洪亮 李波 卢星 杨明摘要:介绍了信息隐藏技术的概念、模型及分类;给出了信息隐藏技术的五大特征;分析了两种典型的信息隐藏算法:时域替换技术和变换域技术;描述了信息隐藏在现实中主要的应用领域;...
  • 【数据库系统设计】数据库安全性

    千次阅读 2020-04-04 22:46:24
    数据库安全性4.1 数据库安全性概述4.1.1 数据库的不安全因素4.2 数据库安全性控制4.2.1 用户身份鉴别4.2.2 存取控制4.2.3 自主存取控制方法4.2.4 授权:授予与回收4.2.5 数据库角色4.2.6 强制存取控制方法4.3 视图...
  • 信息安全复习

    千次阅读 2021-01-02 22:12:11
    报文鉴别码MAC对散列进行一次加密后的结果,对称加密体制下可以防伪造,非对称加密体制下可以防伪造,防否认(ppt3) 数字签名的实现过程:(ppt3) 一、加解密原理分类(加解密体制) 二、消息摘要的含义、特征...
  • 数据库-数据库安全性

    千次阅读 2019-09-02 23:46:10
    这篇博客内容有些琐碎繁杂,我整理的时候有很多上课时老师没有讲的,但我自己在看的时候看了看...数据库安全性 1、数据库安全性概述 1)、数据库的不完全因素 2)、安全标准简介 2、数据库安全性控制 1)、用户...
  • 什么是线程安全性

    千次阅读 2007-06-23 22:57:00
    也许你会惊讶,并发编程并不会涉及过多的线程或锁,不会多于建筑工程...编写线程安全的代码,本质上就是管理对状态(state)的访问,而且通常都是共享的、可变的状态。通俗地说,一个对象的状态就是它的数据,存储在状
  • 音频信息隐藏技术研究

    千次阅读 2013-11-16 10:46:09
    与此不同,信息隐藏作为近年迅速发展起来的一种保密通信技术,它首先将待传输信息嵌入到诸如音频、视频、文件等载体中,使得非法第三方不易觉察到秘密信息的存在,然后通过携密载体的传送,实现秘密信息的保密传输。...
  • (六)数据库安全性

    千次阅读 2017-05-01 13:09:49
    一、数据库安全性控制 1.用户标记与鉴别 用户标识与鉴别是系统提供的最外层安全保护措施。其方法是由系统提供一定的方式让用户标识自己的名字或身份。每次用户要求进入系统时,由系统进行核对,通过鉴定后才提供...
  • 信息安全五大特性

    千次阅读 2021-02-27 18:47:11
    1.完整:指信息在传输、交换、存储和处理过程保持非修改、非破坏和非丢失的特性,即保持信息原样,使信息能正确生成、存储、传输,这是最基本的安全特征。 1.1 完整实现 数据完整保护有两种基本方法:一是...
  • 安全性基本概念

    千次阅读 2007-04-28 18:48:00
    计算机安全性所谓计算机系统安全性,是为计算机系统建立和采取的各种安全保护措施,以保护计算机系统中的硬件、软件及数据,防止其因偶然或恶意的原因使系统遭到破坏,数据遭到更改或泄露等。计算机安全不仅涉及到...
  • 一、本章要点 1)加密和解密、身份认证(数字签名、密钥、...2)系统的访问控制技术、数据的完整性、数据与文件的加密、通信的安全性、系统的安全性设计。 二、信息系统安全体系 信息安全的5个要素:机密性、完整性、
  • 第九章数据库安全性  一、选择题 1. 以下( D)不属于实现数据库系统安全性的主要技术和方法。 A. 存取控制技术 B. 视图技术 C. 审计技术 D. 出入机房登记和加锁 2. SQL中的视图提高了数据库系统的...
  • 数据库的安全性保护数据库以防止不合法使用所造成的数据泄露、更改或破坏 4.1.1数据库的不安全因素以及应对措施 非授权用户对数据库的恶意存储和破坏:用户身份鉴别、存取控制、视图 数据库中重要或敏感的...
  • 网络信息安全期末复习要点

    千次阅读 2019-12-24 14:04:28
    从用户角度看,网络安全主要是保障个人数据或企业的信息在网络中的保密、完整、不可否认,防止信息的泄露和破坏,防止信息资源的非授权访问。对于网络管理者来说,网络安全的主要任务是保障合法...
  • 安全性主要取决于第三方区分载体 对象和隐写对象之间差别的能力 载体对象要含有足够多的冗余以便能被秘密信 息所替换 同一载体对象不应当被使用两次 隐写术与密码术的不同: 除了试图隐藏信息的内容,更进一步...
  • 信息安全期末复习整理

    万次阅读 多人点赞 2019-10-18 19:45:02
    信息安全期末复习整理。适用于韦老师2019《信息安全期末考试》。
  • 信息隐藏与数字水印技术

    千次阅读 2005-04-14 11:32:00
    信息隐藏则主要研究如何将某一机密信息秘密隐藏于另一公开的信息中,然后通过公开信息的传输来传递机密信息。对加密通信而言,可能的监测者或非法拦截者可通过截取密文,并对其进行破译,或将密文进行破坏后再发送...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 106,888
精华内容 42,755
关键字:

信息隐藏的安全性是指