糊言亂語(yǔ)

          志未半斤, 才無(wú)八兩. 有苦有樂(lè), 糊涂過(guò)活。
          posts - 25, comments - 7, trackbacks - 0, articles - 42
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          加密算法與實(shí)例

          Posted on 2007-12-05 22:09 Stanley Sun 閱讀(543) 評(píng)論(1)  編輯  收藏

          概念:

          1.數(shù)字摘要:解決在安全的通信環(huán)境下,保證信息的唯一的一種方式。通常使用MD5/SHA-1等算法完成摘要。一般比如大家在網(wǎng)上下載軟件光盤(pán)時(shí)都會(huì)看到一個(gè)MD5值就是起到這個(gè)數(shù)字摘要的作用。在網(wǎng)絡(luò)的環(huán)境中發(fā)送者把消息和數(shù)字摘要一同發(fā)送給接收者,接收者使用發(fā)送者相同的算法對(duì)消息加密,看是否與發(fā)送者發(fā)送過(guò)來(lái)的數(shù)字摘要相同,如果相同就證明消息沒(méi)有給篡改過(guò)。下面是一個(gè)最為簡(jiǎn)單的示例:

          import java.security.*;
          public class myDigest {
            public static void main(String[] args)  {
              myDigest my=new myDigest();
              my.testDigest();
            }
            public void testDigest()
            {
             try {
               String myinfo="我的測(cè)試信息";
              //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");
                java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");
                alga.update(myinfo.getBytes());
                byte[] digesta=alga.digest();
                System.out.println("本信息摘要是:"+byte2hex(digesta));
                //通過(guò)某中方式傳給其他人你的信息(myinfo)和摘要(digesta) 對(duì)方可以判斷是否更改或傳輸正常
                java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");
                algb.update(myinfo.getBytes());
                if (algb.isEqual(digesta,algb.digest())) {
                   System.out.println("信息檢查正常");
                 }
                 else
                  {
                    System.out.println("摘要不相同");
                   }
             }
             catch (java.security.NoSuchAlgorithmException ex) {
               System.out.println("非法摘要算法");
             }
            }
            public String byte2hex(byte[] b) //二行制轉(zhuǎn)字符串
              {
               String hs="";
               String stmp="";
               for (int n=0;n<b.length;n++)
                {
                 stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                 if (stmp.length()==1) hs=hs+"0"+stmp;
                 else hs=hs+stmp;
                 if (n<b.length-1)  hs=hs+":";
                }
               return hs.toUpperCase();
              }
          }
          

          2.電子簽名:對(duì)數(shù)據(jù)信息的發(fā)生者身份的認(rèn)定,它是一種抽象的概念而不是一種具體技術(shù)。實(shí)現(xiàn)電子簽名的技術(shù)手段目前有多種,比如基于公鑰密碼技術(shù)的數(shù)字簽名;或用一個(gè)獨(dú)一無(wú)二的以生物特征統(tǒng)計(jì)學(xué)為基礎(chǔ)的識(shí)別標(biāo)識(shí),例如手印、聲音印記或視網(wǎng)膜掃描的識(shí)別;手書(shū)簽名和圖章的電子圖象的模式識(shí)別;表明身份的密碼代號(hào)(對(duì)稱算法);基于量子力學(xué)的計(jì)算機(jī)等等。


          3.數(shù)字簽名:所謂數(shù)字簽名就是利用通過(guò)某種密碼運(yùn)算生成的一系列符號(hào)及代碼組成電子密碼進(jìn)行"簽名",來(lái)代替書(shū)寫(xiě)簽名或印章,對(duì)于這種電子式的簽名在技術(shù)上還可進(jìn)行算法驗(yàn)證,其驗(yàn)證的準(zhǔn)確度是在物理世界中與手工簽名和圖章的驗(yàn)證是無(wú)法相比的。一般實(shí)現(xiàn)數(shù)字簽名的方法是通過(guò)生成的密鑰對(duì)的私鑰對(duì)用戶生成的數(shù)字消息進(jìn)行DSA(Digital Signature Algorithm (DSA)是Schnorr和ElGamal簽名算法的變種,被美國(guó)NIST作為DSS(DigitalSignature Standard))加密實(shí)現(xiàn)的。實(shí)現(xiàn)代碼如下:

             */
           import java.security.*;
           import java.security.spec.*;
          public class testdsa {
            public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception {
                  testdsa my=new testdsa();
                  my.run();
            }
            public void run()
            {
            //數(shù)字簽名生成密鑰
            //第一步生成密鑰對(duì),如果已經(jīng)生成過(guò),本過(guò)程就可以跳過(guò),對(duì)用戶來(lái)講myprikey.dat要保存在本地
            //而mypubkey.dat給發(fā)布給其它用戶
             if ((new java.io.File("myprikey.dat")).exists()==false) {
                 if (generatekey()==false) {
                     System.out.println("生成密鑰對(duì)敗");
                     return;
                    };
                  }
          //第二步,此用戶
          //從文件中讀入私鑰,對(duì)一個(gè)字符串進(jìn)行簽名后保存在一個(gè)文件(myinfo.dat)中
          //并且再把myinfo.dat發(fā)送出去
          //為了方便數(shù)字簽名也放進(jìn)了myifno.dat文件中,當(dāng)然也可分別發(fā)送
            try {
            java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
            PrivateKey myprikey=(PrivateKey)in.readObject();
            in.close();
           // java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509);
           //java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec
            String myinfo="這是我的信息";    //要簽名的信息
            //用私鑰對(duì)信息生成數(shù)字簽名
            java.security.Signature signet=java.security.Signature.getInstance("DSA");
            signet.initSign(myprikey);
            signet.update(myinfo.getBytes());
            byte[] signed=signet.sign();  //對(duì)信息的數(shù)字簽名
            System.out.println("signed(簽名內(nèi)容)="+byte2hex(signed));
           //把信息和數(shù)字簽名保存在一個(gè)文件中
            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
            out.writeObject(myinfo);
            out.writeObject(signed);
            out.close();
            System.out.println("簽名并生成文件成功");
            }
            catch (java.lang.Exception e) {
              e.printStackTrace();
              System.out.println("簽名并生成文件失敗");
            };
            //第三步
            //其他人通過(guò)公共方式得到此戶的公鑰和文件
            //其他人用此戶的公鑰,對(duì)文件進(jìn)行檢查,如果成功說(shuō)明是此用戶發(fā)布的信息.
            //
            try {
             java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
             PublicKey pubkey=(PublicKey)in.readObject();
             in.close();
             System.out.println(pubkey.getFormat());
             in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
             String info=(String)in.readObject();
             byte[] signed=(byte[])in.readObject();
             in.close();
            java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
            signetcheck.initVerify(pubkey);
            signetcheck.update(info.getBytes());
            if (signetcheck.verify(signed)) {
            System.out.println("info="+info);
             System.out.println("簽名正常");
            }
            else  System.out.println("非簽名正常");
            }
            catch (java.lang.Exception e) {e.printStackTrace();};
            }
            //生成一對(duì)文件myprikey.dat和mypubkey.dat---私鑰和公鑰,
            //公鑰要用戶發(fā)送(文件,網(wǎng)絡(luò)等方法)給其它用戶,私鑰保存在本地
            public boolean generatekey()
            {
              try {
            java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
           // SecureRandom secrand=new SecureRandom();
           // secrand.setSeed("tttt".getBytes()); //初始化隨機(jī)產(chǎn)生器
           // keygen.initialize(576,secrand);     //初始化密鑰生成器
            keygen.initialize(512);
            KeyPair keys=keygen.genKeyPair();
          //  KeyPair keys=keygen.generateKeyPair(); //生成密鑰組
            PublicKey pubkey=keys.getPublic();
            PrivateKey prikey=keys.getPrivate();
            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
            out.writeObject(prikey);
            out.close();
            System.out.println("寫(xiě)入對(duì)象 prikeys ok");
            out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
             out.writeObject(pubkey);
             out.close();
             System.out.println("寫(xiě)入對(duì)象 pubkeys ok");
             System.out.println("生成密鑰對(duì)成功");
             return true;
            }
            catch (java.lang.Exception e) {
             e.printStackTrace();
             System.out.println("生成密鑰對(duì)失敗");
             return false;
             };
            }
            public String byte2hex(byte[] b)
              {
               String hs="";
               String stmp="";
               for (int n=0;n<b.length;n++)
                {
                 stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                 if (stmp.length()==1) hs=hs+"0"+stmp;
                 else hs=hs+stmp;
                 if (n<b.length-1)  hs=hs+":";
                }
               return hs.toUpperCase();
              }
          }    把他的公鑰的信息及簽名發(fā)給其它用戶
          


          4.PKI(公鑰基礎(chǔ)設(shè)施):


          評(píng)論

          # re: 加密算法與實(shí)例  回復(fù)  更多評(píng)論   

          2009-05-30 11:38 by czy
          88

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 波密县| 双柏县| 桦南县| 普兰县| 攀枝花市| 秭归县| 金湖县| 延长县| 乌鲁木齐县| 教育| 城口县| 庄浪县| 伽师县| 铜山县| 合肥市| 威海市| 宣恩县| 萨迦县| 华亭县| 鸡泽县| 伊春市| 澳门| 运城市| 株洲县| 肇源县| 巴彦淖尔市| 闽侯县| 五寨县| 蕉岭县| 山西省| 陆河县| 阿合奇县| 荆州市| 临夏市| 汉沽区| 新田县| 巴中市| 宜宾县| 哈密市| 杨浦区| 高青县|