找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3517|回复: 0

[原]VC++信息安全编程(15)基于一阶Bézier曲线的信息隐藏

[复制链接]
发表于 2012-3-8 15:03:31 | 显示全部楼层 |阅读模式
信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是透明的。
传统的信息隐藏起源于古老的隐写术。如在古希腊战争中,为了安全地传送军事情报,奴隶主剃光奴隶 的头发,将情报文在奴隶的头皮上,待头发长起后再派出去传送消息。我国古代也早有以藏头诗、藏尾诗、漏格诗以及绘画等形式,将要表达的意思和“密语”隐藏在诗文或画卷中的特定位置,一般人只注意诗或画的表面意境,而不会去注意或破解隐藏其中的密语。   信息隐藏的发展历史可以一直追溯到"匿形术(Steganography)"的使用。"匿形术"一词来源于古希腊文中"隐藏的"和"图形"两个词语的组合。虽然"匿形术"与"密码术(Cryptography)"都是致力于信息的保密技术,但是,两者的设计思想却完全不同。"密码术"主要通过设计加密技术,使保密信息不可读,但是对于非授权者来讲,虽然他无法获知保密信息的具体内容,却能意识到保密信息的存在。而"匿形术"则致力于通过设计精妙的方法,使得非授权者根本无从得知保密信息的存在与否。相对于现代密码学来讲,信息隐藏的最大优势在于它并不限制对主信号的存取和访问,而是致力于签字信号的安全保密性。
我们来实践一个基于一阶Bézier曲线的信息隐藏编程实例 ,需要一定的数学基础,请见代码分析。
  1. #ifdef _DEBUG
  2. #define new DEBUG_NEW
  3. #undef THIS_FILE
  4. static char THIS_FILE[] = __FILE__;
  5. #endif
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CAboutDlg dialog used for App About
  8. class CAboutDlg : public CDialog
  9. {
  10. public:
  11.         CAboutDlg();
  12. // Dialog Data
  13.         //{{AFX_DATA(CAboutDlg)
  14.         enum { IDD = IDD_ABOUTBOX };
  15.         //}}AFX_DATA
  16.         // ClassWizard generated virtual function overrides
  17.         //{{AFX_VIRTUAL(CAboutDlg)
  18.         protected:
  19.         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  20.         //}}AFX_VIRTUAL
  21. // Implementation
  22. protected:
  23.         //{{AFX_MSG(CAboutDlg)
  24.         //}}AFX_MSG
  25.         DECLARE_MESSAGE_MAP()
  26. };
  27. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  28. {
  29.         //{{AFX_DATA_INIT(CAboutDlg)
  30.         //}}AFX_DATA_INIT
  31. }
  32. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  33. {
  34.         CDialog::DoDataExchange(pDX);
  35.         //{{AFX_DATA_MAP(CAboutDlg)
  36.         //}}AFX_DATA_MAP
  37. }
  38. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  39.         //{{AFX_MSG_MAP(CAboutDlg)
  40.                 // No message handlers
  41.         //}}AFX_MSG_MAP
  42. END_MESSAGE_MAP()
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CDataHideInBMPBZDlg dialog
  45. CDataHideInBMPBZDlg::CDataHideInBMPBZDlg(CWnd* pParent /*=NULL*/)
  46.         : CDialog(CDataHideInBMPBZDlg::IDD, pParent)
  47. {
  48.         //{{AFX_DATA_INIT(CDataHideInBMPBZDlg)
  49.                 // NOTE: the ClassWizard will add member initialization here
  50.         //}}AFX_DATA_INIT
  51.         // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  52.         m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  53. }
  54. void CDataHideInBMPBZDlg::DoDataExchange(CDataExchange* pDX)
  55. {
  56.         CDialog::DoDataExchange(pDX);
  57.         //{{AFX_DATA_MAP(CDataHideInBMPBZDlg)
  58.                 // NOTE: the ClassWizard will add DDX and DDV calls here
  59.         //}}AFX_DATA_MAP
  60. }
  61. BEGIN_MESSAGE_MAP(CDataHideInBMPBZDlg, CDialog)
  62.         //{{AFX_MSG_MAP(CDataHideInBMPBZDlg)
  63.         ON_WM_SYSCOMMAND()
  64.         ON_WM_PAINT()
  65.         ON_WM_QUERYDRAGICON()
  66.         ON_BN_CLICKED(IDC_BASEBMP_HIDE, OnBasebmpHide)
  67.         ON_BN_CLICKED(IDC_HIDEFILE, OnHidefile)
  68.         ON_BN_CLICKED(IDC_DOHIDE, OnDohide)
  69.         ON_BN_CLICKED(IDC_BASEBMP_RESUME, OnBasebmpResume)
  70.         ON_BN_CLICKED(IDC_BASEFILE, OnBasefile)
  71.         ON_BN_CLICKED(IDC_RESUMEDATA, OnResumedata)
  72.         //}}AFX_MSG_MAP
  73. END_MESSAGE_MAP()
  74. /////////////////////////////////////////////////////////////////////////////
  75. // CDataHideInBMPBZDlg message handlers
  76. BOOL CDataHideInBMPBZDlg::OnInitDialog()
  77. {
  78.         CDialog::OnInitDialog();
  79.         // Add "About..." menu item to system menu.
  80.         // IDM_ABOUTBOX must be in the system command range.
  81.         ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  82.         ASSERT(IDM_ABOUTBOX < 0xF000);
  83.         CMenu* pSysMenu = GetSystemMenu(FALSE);
  84.         if (pSysMenu != NULL)
  85.         {
  86.                 CString strAboutMenu;
  87.                 strAboutMenu.LoadString(IDS_ABOUTBOX);
  88.                 if (!strAboutMenu.IsEmpty())
  89.                 {
  90.                         pSysMenu->AppendMenu(MF_SEPARATOR);
  91.                         pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  92.                 }
  93.         }
  94.         // Set the icon for this dialog.  The framework does this automatically
  95.         //  when the application's main window is not a dialog
  96.         SetIcon(m_hIcon, TRUE);                        // Set big icon
  97.         SetIcon(m_hIcon, FALSE);                // Set small icon
  98.        
  99.         // TODO: Add extra initialization here
  100.         t=0.035;                //融合系数
  101.         m_bBaseBMPHide=false;
  102.         m_bBaseBMPResume=false;
  103.         m_bHidefile=false;
  104.         m_bBasefile=false;
  105.         GetDlgItem(IDC_DOHIDE)->EnableWindow(m_bBaseBMPHide && m_bHidefile);
  106.         GetDlgItem(IDC_RESUMEDATA)->EnableWindow(m_bBaseBMPResume && m_bBasefile);
  107.         return TRUE;  // return TRUE  unless you set the focus to a control
  108. }
  109. void CDataHideInBMPBZDlg::OnSysCommand(UINT nID, LPARAM lParam)
  110. {
  111.         if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  112.         {
  113.                 CAboutDlg dlgAbout;
  114.                 dlgAbout.DoModal();
  115.         }
  116.         else
  117.         {
  118.                 CDialog::OnSysCommand(nID, lParam);
  119.         }
  120. }
  121. // If you add a minimize button to your dialog, you will need the code below
  122. //  to draw the icon.  For MFC applications using the document/view model,
  123. //  this is automatically done for you by the framework.
  124. void CDataHideInBMPBZDlg::OnPaint()
  125. {
  126.         if (IsIconic())
  127.         {
  128.                 CPaintDC dc(this); // device context for painting
  129.                 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  130.                 // Center icon in client rectangle
  131.                 int cxIcon = GetSystemMetrics(SM_CXICON);
  132.                 int cyIcon = GetSystemMetrics(SM_CYICON);
  133.                 CRect rect;
  134.                 GetClientRect(&rect);
  135.                 int x = (rect.Width() - cxIcon + 1) / 2;
  136.                 int y = (rect.Height() - cyIcon + 1) / 2;
  137.                 // Draw the icon
  138.                 dc.DrawIcon(x, y, m_hIcon);
  139.         }
  140.         else
  141.         {
  142.                 CDialog::OnPaint();
  143.         }
  144. }
  145. // The system calls this to obtain the cursor to display while the user drags
  146. //  the minimized window.
  147. HCURSOR CDataHideInBMPBZDlg::OnQueryDragIcon()
  148. {
  149.         return (HCURSOR) m_hIcon;
  150. }
  151. unsigned char CDataHideInBMPBZDlg::HideCalculate(unsigned char B, unsigned char H)
  152. {
  153.         unsigned char R=(int)((1-t)*B+0.5f)+(int)(t*H+0.5f);
  154.         return R;
  155. }
  156. unsigned char CDataHideInBMPBZDlg::ShowCalculate(unsigned char C, unsigned char B)
  157. {
  158.         unsigned char R=(int)((C- (int)((1-t)*B+0.5f))/t+0.5f);
  159.         if(R%32>15)
  160.                 R+=15;
  161.         R=(int)(R/32.0f+0.5f);
  162.         return R;
  163. }
  164. void CDataHideInBMPBZDlg::OnBasebmpHide()
  165. {
  166.         // TODO: Add your control notification handler code here
  167.         CFileDialog dlg(TRUE,"bmp","*.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"载体位图文件(*.bmp)|*.bmp||",NULL);
  168.         if(dlg.DoModal()==IDOK)
  169.         {
  170.                 m_bBaseBMPHide=true;
  171.                 m_sCarrierFileHide=dlg.GetPathName();
  172.                 GetDlgItem(IDC_BASEBMP_HIDE)->SetWindowText(m_sCarrierFileHide);
  173.         }
  174.         else
  175.                 m_bBaseBMPHide=false;
  176.         GetDlgItem(IDC_DOHIDE)->EnableWindow(m_bBaseBMPHide && m_bHidefile);
  177. }
  178. void CDataHideInBMPBZDlg::OnHidefile()
  179. {
  180.         // TODO: Add your control notification handler code here
  181.         CFileDialog dlg(TRUE,"*","*.*",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"待隐藏文件(*.*)|*.*||",NULL);
  182.         if(dlg.DoModal()==IDOK)
  183.         {
  184.                 m_bHidefile=true;
  185.                 m_sHideFile=dlg.GetPathName();
  186.                 m_sHideFileName=dlg.GetFileName();
  187.                 GetDlgItem(IDC_HIDEFILE)->SetWindowText(m_sHideFileName);
  188.         }
  189.         else
  190.                 m_bHidefile=false;
  191.         GetDlgItem(IDC_DOHIDE)->EnableWindow(m_bBaseBMPHide && m_bHidefile);
  192. }
  193. void CDataHideInBMPBZDlg::OnDohide()
  194. {
  195.         // TODO: Add your control notification handler code here
  196.         CFile BaseFile,HideFile;
  197.         DWORD BaseFileLen,HideFileLen;
  198.        
  199.         unsigned char* BaseData;
  200.         unsigned char* HideData;
  201.        
  202.         if(m_bBaseBMPHide==true && m_bHidefile==true)
  203.         {
  204.                 BaseFile.Open(m_sCarrierFileHide,CFile::modeReadWrite);
  205.                 BaseFileLen=BaseFile.GetLength();
  206.                 HideFile.Open(m_sHideFile,CFile::modeReadWrite);
  207.                 HideFileLen=HideFile.GetLength();
  208.                
  209.                 //信息头:文件名*文件长*
  210.                 CString        InfoHead;
  211.                 InfoHead.Format("%s*%d*",m_sHideFileName,HideFileLen);
  212.                 int HeadLen=InfoHead.GetLength();
  213.                
  214.                 if(BaseFileLen<((HeadLen+HideFileLen)*8)/3+100)
  215.                 {
  216.                         AfxMessageBox("待隐藏文件过大!请换一较大载体位图文件。");
  217.                         return;
  218.                 }
  219.                 BaseData=new unsigned char[BaseFileLen];
  220.                 BaseFile.Read(BaseData,BaseFileLen);
  221.                 HideData=new unsigned char[BaseFileLen];
  222.                 //对明文进行组帧
  223.                 for(int k=0;k<HeadLen;k++)
  224.                         HideData[k]=InfoHead.GetAt(k);
  225.                 HideFile.Read(HideData+HeadLen,HideFileLen);
  226.                 for(DWORD kk=HeadLen+HideFileLen;kk<BaseFileLen;kk++)
  227.                         HideData[kk]=0;
  228.                 if(BaseData[28]!=24)
  229.                 {
  230.                         AfxMessageBox("载体文件格式错误!");
  231.                         BaseFile.Close();
  232.                         if(BaseData!=NULL)
  233.                                 delete BaseData;
  234.                         return;
  235.                 }
  236.                 unsigned char Temp=0;
  237.                 DWORD j=0;
  238.                 for(DWORD i=54;i<BaseFileLen;i++)
  239.                 {
  240.                         Temp=((HideData[j]&224)>>5)<<5;                //1
  241.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  242.                         i++;
  243.                         Temp=((HideData[j]&28)>>2)<<5;                //2
  244.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  245.                         i++;
  246.                         Temp=(HideData[j]&3)<<1;                        //3
  247.                         j++;
  248.                         Temp|=(HideData[j]&128)>>7;
  249.                         Temp*=32;
  250.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  251.                         i++;
  252.                         Temp=((HideData[j]&112)>>4)<<5;                //4
  253.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  254.                         i++;
  255.                         Temp=((HideData[j]&14)>>1)<<5;                //5
  256.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  257.                         i++;
  258.                         Temp=(HideData[j]&1)<<2;                        //6
  259.                         j++;
  260.                         Temp|=(HideData[j]&192)>>6;
  261.                         Temp*=32;
  262.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  263.                         i++;
  264.                         Temp=((HideData[j]&56)>>3)<<5;                //7
  265.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  266.                         i++;
  267.                         Temp=(HideData[j]&7)<<5;                        //8
  268.                         BaseData[i]=HideCalculate(BaseData[i],Temp);
  269.                         j++;
  270.                 }
  271.                 BaseFile.Close();
  272.                 HideFile.Close();
  273.                
  274.                 CFile file;
  275.                 file.Open("融合图像.bmp",CFile::modeCreate|CFile::modeReadWrite);
  276.                 file.Write(BaseData,BaseFileLen);
  277.                 file.Close();
  278.                 AfxMessageBox("信息隐藏完毕!");
  279.                
  280.                 if(BaseData!=NULL)
  281.                         delete BaseData;
  282.                 if(HideData!=NULL)
  283.                         delete HideData;
  284.         }               
  285. }
  286. void CDataHideInBMPBZDlg::OnBasebmpResume()
  287. {
  288.         // TODO: Add your control notification handler code here
  289.         CFileDialog dlg(TRUE,"bmp","*.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"载体位图文件(*.bmp)|*.bmp||",NULL);
  290.         if(dlg.DoModal()==IDOK)
  291.         {
  292.                 m_bBaseBMPResume=true;
  293.                 m_sCarrierFileResume=dlg.GetPathName();
  294.                 GetDlgItem(IDC_BASEBMP_RESUME)->SetWindowText(m_sCarrierFileResume);
  295.         }
  296.         else
  297.                 m_bBaseBMPResume=false;
  298.         GetDlgItem(IDC_RESUMEDATA)->EnableWindow(m_bBaseBMPResume && m_bBasefile);
  299. }
  300. void CDataHideInBMPBZDlg::OnBasefile()
  301. {
  302.         // TODO: Add your control notification handler code here
  303.         CFileDialog dlg(TRUE,"bmp","*.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"原始文件(*.bmp)|*.bmp||",NULL);
  304.         if(dlg.DoModal()==IDOK)
  305.         {
  306.                 m_bBasefile=true;
  307.                 m_sBaseFile=dlg.GetPathName();
  308.                 GetDlgItem(IDC_BASEFILE)->SetWindowText(m_sBaseFile);
  309.         }
  310.         else
  311.                 m_bBasefile=false;
  312.         GetDlgItem(IDC_RESUMEDATA)->EnableWindow(m_bBaseBMPResume && m_bBasefile);
  313. }
  314. void CDataHideInBMPBZDlg::OnResumedata()
  315. {
  316.         // TODO: Add your control notification handler code here
  317.         CFile BaseFile;
  318.         CFile CarrierFile;
  319.         DWORD BaseFileLen;
  320.         DWORD CarrierFileLen;
  321.        
  322.         unsigned char* BaseData;
  323.         unsigned char* CarrierData;
  324.        
  325.         if(m_bBaseBMPResume==true && m_bBasefile==true)
  326.         {
  327.                 CarrierFile.Open(m_sCarrierFileResume,CFile::modeReadWrite);
  328.                 CarrierFileLen=CarrierFile.GetLength();
  329.                 BaseFile.Open(m_sBaseFile,CFile::modeReadWrite);
  330.                 BaseFileLen=BaseFile.GetLength();
  331.                 if(BaseFileLen!=CarrierFileLen)
  332.                 {
  333.                         AfxMessageBox("选取的不是充作载体的原始文件!");
  334.                         CarrierFile.Close();
  335.                         BaseFile.Close();
  336.                         return;
  337.                 }
  338.                
  339.                 CarrierData=new unsigned char[CarrierFileLen];
  340.                 CarrierFile.Read(CarrierData,CarrierFileLen);
  341.                 BaseData=new unsigned char[CarrierFileLen];
  342.                 BaseFile.Read(BaseData,CarrierFileLen);
  343.                 if(CarrierData[28]!=24)
  344.                 {
  345.                         AfxMessageBox("载体文件格式错误!");
  346.                         CarrierFile.Close();
  347.                         BaseFile.Close();
  348.                         if(CarrierData!=NULL)
  349.                                 delete CarrierData;
  350.                         if(BaseData!=NULL)
  351.                                 delete BaseData;
  352.                         return;
  353.                 }
  354.                 if(BaseData[28]!=24)
  355.                 {
  356.                         AfxMessageBox("原始文件格式错误!");
  357.                         CarrierFile.Close();
  358.                         BaseFile.Close();
  359.                         if(CarrierData!=NULL)
  360.                                 delete CarrierData;
  361.                         if(BaseData!=NULL)
  362.                                 delete BaseData;
  363.                         return;
  364.                 }
  365.                 unsigned char Temp=0;
  366.                 DWORD j=0;
  367.                 for(DWORD i=54;i<CarrierFileLen;i++)
  368.                 {
  369.                         Temp=(ShowCalculate(CarrierData[i],BaseData[i])&7)<<5;
  370.                         i++;
  371.                         Temp|=(ShowCalculate(CarrierData[i],BaseData[i])&7)<<2;
  372.                         i++;
  373.                         Temp|=(ShowCalculate(CarrierData[i],BaseData[i])&6)>>1;
  374.                         CarrierData[j]=Temp;
  375.                         j++;
  376.                         Temp=(ShowCalculate(CarrierData[i],BaseData[i])&1)<<7;
  377.                         i++;
  378.                         Temp|=(ShowCalculate(CarrierData[i],BaseData[i])&7)<<4;
  379.                         i++;
  380.                         Temp|=(ShowCalculate(CarrierData[i],BaseData[i])&7)<<1;
  381.                         i++;
  382.                         Temp|=(ShowCalculate(CarrierData[i],BaseData[i])&4)>>2;
  383.                         CarrierData[j]=Temp;
  384.                         j++;
  385.                         Temp=(ShowCalculate(CarrierData[i],BaseData[i])&3)<<6;
  386.                         i++;
  387.                         Temp|=(ShowCalculate(CarrierData[i],BaseData[i])&7)<<3;
  388.                         i++;
  389.                         Temp|=ShowCalculate(CarrierData[i],BaseData[i])&7;
  390.                         CarrierData[j]=Temp;
  391.                         j++;
  392.                 }
  393.                 BaseFile.Close();
  394.                 CarrierFile.Close();
  395.                 j=0;
  396.                 CString FileName="";
  397.                 while(true)
  398.                 {
  399.                         if(CarrierData[j]=='*')
  400.                         {
  401.                                 j++;
  402.                                 break;
  403.                         }
  404.                         else
  405.                         {
  406.                                 FileName+=CString(CarrierData[j]);
  407.                                 j++;
  408.                         }
  409.                 }
  410.                 CString FileLen="";
  411.                 while(true)
  412.                 {
  413.                         if(CarrierData[j]=='*')
  414.                         {
  415.                                 j++;
  416.                                 break;
  417.                         }
  418.                         else
  419.                         {
  420.                                 FileLen+=CString(CarrierData[j]);
  421.                                 j++;
  422.                         }
  423.                 }
  424.                 BaseFileLen=atoi(FileLen);
  425.                 CFile file;
  426.                 file.Open(FileName,CFile::modeCreate|CFile::modeReadWrite);
  427.                 file.Write(CarrierData+j,BaseFileLen);
  428.                 file.Close();
  429.                 AfxMessageBox("信息恢复完毕!");
  430.                 if(BaseData!=NULL)
  431.                         delete BaseData;
  432.                 if(CarrierData!=NULL)
  433.                         delete CarrierData;
  434.         }       
  435. }
复制代码
作者:yincheng01 发表于2011-12-15 7:46:03 原文链接

您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-29 08:07 , Processed in 0.013287 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表