主頁 > 區塊鏈 > 密碼學DAY2

密碼學DAY2

2020-09-10 03:05:42 區塊鏈

目錄

  • 1.1 加密模式
  • 1.2 填充模式
  • 1.3 訊息摘要
    • 1.3.1 特點
    • 1.3.2 獲取字串訊息摘要
    • 1.3.3 base64編碼
    • 1.3.4 其他數字摘要演算法
    • 1.3.5 獲取檔案訊息摘要
  • 1.4 非對稱加密
    • 1.4.1 生成公鑰和私鑰
    • 1.4.2 私鑰加密
    • 1.4.3 私鑰加密私鑰解密
    • 1.4.4 私鑰加密公鑰解密
  • 1.5 數字簽名
    • 1.5.1 簡單認識
    • 1.5.2 基本原理
    • 1.5.3 數字證書
    • 1.5.4 代碼實作

1.1 加密模式

加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html

ECB
ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進行獨立加密

  • 優點 : 可以并行處理資料
  • 缺點 : 同樣的原文生成同樣的密文, 不能很好的保護資料
  • 同時加密,原文是一樣的,加密出來的密文也是一樣的

CBC
CBC : Cipher-block chaining, 密碼塊鏈接. 每個明文塊先與前一個密文塊進行異或后,再進行加密,在這種方法中,每個密文塊都依賴于它前面的所有明文塊

  • 優點 : 同樣的原文生成的密文不一樣
  • 缺點 : 串行處理資料

1.2 填充模式

  • 當需要按塊處理的資料, 資料長度不符合塊處理需求時, 按照一定的方法填充滿塊長的規則
    NoPadding

  • 不填充.
    -在DES加密演算法下, 要求原文長度必須是8byte的整數倍
    -在AES加密演算法下, 要求原文長度必須是16byte的整數倍
    PKCS5Padding

  • 資料塊的大小為8位, 不夠就補足

Tips

  • 默認情況下, 加密模式和填充模式為 : ECB/PKCS5Padding
  • 如果使用CBC模式, 在初始化Cipher物件時, 需要增加引數, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());

加密模式和填充模式

AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

加密模式和填充模式例子

package com.atguigu.desaes;

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class DesDemo {
    // DES加密演算法,key的大小必須是8個位元組

    public static void main(String[] args) throws Exception {
        String input ="硅谷";
        // DES加密演算法,key的大小必須是8個位元組
        String key = "12345678";
        // 指定獲取Cipher的演算法,如果沒有指定加密模式和填充模式,ECB/PKCS5Padding就是默認值
        //     String transformation = "DES"; // 9PQXVUIhaaQ=
        //String transformation = "DES/ECB/PKCS5Padding"; // 9PQXVUIhaaQ=
        // CBC模式,必須指定初始向量,初始向量中密鑰的長度必須是8個位元組
        //String transformation = "DES/CBC/PKCS5Padding"; // 9PQXVUIhaaQ=
        // NoPadding模式,原文的長度必須是8個位元組的整倍數 ,所以必須把 硅谷改成硅谷12
        String transformation = "DES/CBC/NoPadding"; // 9PQXVUIhaaQ=
        // 指定獲取密鑰的演算法
        String algorithm = "DES";
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);
//        String s = dncryptDES(encryptDES, key, transformation, algorithm);
//        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密資料
     *
     * @param input          : 原文
     * @param key            : 密鑰(DES,密鑰的長度必須是8個位元組)
     * @param transformation : 獲取Cipher物件的演算法
     * @param algorithm      : 獲取密鑰的演算法
     * @return : 密文
     * @throws Exception
     */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 獲取加密物件
        Cipher cipher = Cipher.getInstance(transformation);
        // 創建加密規則
        // 第一個引數key的位元組
        // 第二個引數表示加密演算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // DECRYPT_MODE: 解密模式
         // 初始向量,引數表示跟誰進行異或,初始向量的長度必須是8位
//        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
         // 初始化加密模式和演算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 輸出加密后的資料
        String encode = Base64.encode(bytes);

        return encode;
    }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密鑰
     * @param transformation : 獲取Cipher物件的演算法
     * @param algorithm      : 獲取密鑰的演算法
     * @throws Exception
     * @return: 原文
     */
    private static String dncryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,獲取Cipher物件
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密鑰規則
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
//        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密
        byte[] bytes = cipher.doFinal(Base64.decode(input));

        return new String(bytes);
    }
}

運行程式:

1.3 訊息摘要

  • 訊息摘要(Message Digest)又稱為數字摘要(Digital Digest)
  • 它是一個唯一對應一個訊息或文本的固定長度的值,它由一個單向Hash加密函式對訊息進行作用而產生
  • 使用數字摘要生成的值是不可以篡改的,為了保證檔案或者值的安全

1.3.1 特點

無論輸入的訊息有多長,計算出來的訊息摘要的長度總是固定的,例如應用MD5演算法摘要的訊息有128個位元位,用SHA-1演算法摘要的訊息最終有160位元位的輸出

只要輸入的訊息不同,對其進行摘要以后產生的摘要訊息也必不相同;但相同的輸入必會產生相同的輸出

訊息摘要是單向、不可逆的

常見演算法 :

- MD5
- SHA1
- SHA256
- SHA512

百度搜索 tomcat ,進入官網下載 ,會經常發現有 sha1,sha512 , 這些都是數字摘要

1.3.2 獲取字串訊息摘要

public class DigestDemo1 {

    public static void main(String[] args) throws Exception{
        // 原文
        String input = "aa";
        // 演算法
        String algorithm = "MD5";
        // 獲取數字摘要物件
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 獲取訊息數字摘要的位元組陣列
        byte[] digest = messageDigest.digest(input.getBytes());
        System.out.println(new String(digest));
    }
}

運行:

1.3.3 base64編碼

public class DigestDemo1 {

    public static void main(String[] args) throws Exception{
        // 原文
        String input = "aa";
        // 演算法
        String algorithm = "MD5";
        // 獲取數字摘要物件
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 訊息數字摘要
        byte[] digest = messageDigest.digest(input.getBytes());
//        System.out.println(new String(digest));
        // base64編碼
        System.out.println(Base64.encode(digest));
    }
}

運行結果:

這里還需要注意一點,數字摘要一般是十六進制的,所以我們在base64轉碼格式的基礎上再轉成16進制,

public class DigestDemo1 {

    public static void main(String[] args) throws Exception{
        // 4124bc0a9335c27f086f24ba207a4912     md5 在線校驗
        // QSS8CpM1wn8IbyS6IHpJEg==             訊息摘要使用的是16進制
        // 原文
        String input = "aa";
        // 演算法
        String algorithm = "MD5";
        // 獲取數字摘要物件
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 訊息數字摘要
        byte[] digest = messageDigest.digest(input.getBytes());
//        System.out.println(new String(digest));
        // base64編碼
//        System.out.println(Base64.encode(digest));
        // 創建物件用來拼接
        StringBuilder sb = new StringBuilder();

        for (byte b : digest) {
            // 轉成 16進制
            String s = Integer.toHexString(b & 0xff);
            //System.out.println(s);
            if (s.length() == 1){
                // 如果生成的字符只有一個,前面補0
                s = "0"+s;
            }
            sb.append(s);
        }
        System.out.println(sb.toString());
        
    }
}

1.3.4 其他數字摘要演算法

public class DigestDemo1 {

    public static void main(String[] args) throws Exception{
        // 4124bc0a9335c27f086f24ba207a4912     md5 在線校驗
        // QSS8CpM1wn8IbyS6IHpJEg==             訊息摘要使用的是16進制
        // 原文
        String input = "aa";
        // 演算法
        String algorithm = "MD5";
        // 獲取數字摘要物件
        String md5 = getDigest(input, "MD5");
        System.out.println(md5);

        String sha1 = getDigest(input, "SHA-1");
        System.out.println(sha1);

        String sha256 = getDigest(input, "SHA-256");
        System.out.println(sha256);

        String sha512 = getDigest(input, "SHA-512");
        System.out.println(sha512);


    }

    private static String toHex(byte[] digest) throws Exception {

//        System.out.println(new String(digest));
        // base64編碼
//        System.out.println(Base64.encode(digest));
        // 創建物件用來拼接
        StringBuilder sb = new StringBuilder();

        for (byte b : digest) {
            // 轉成 16進制
            String s = Integer.toHexString(b & 0xff);
            if (s.length() == 1){
                // 如果生成的字符只有一個,前面補0
                s = "0"+s;
            }
            sb.append(s);
        }
        System.out.println("16進制資料的長度:" + sb.toString().getBytes().length);
        return sb.toString();
    }

    private static String getDigest(String input, String algorithm) throws Exception {
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 訊息數字摘要
        byte[] digest = messageDigest.digest(input.getBytes());
        System.out.println("密文的位元組長度:" + digest.length);

        return toHex(digest);
    }
}

運行結果:

1.3.5 獲取檔案訊息摘要

public class DigestDemo {

    public static void main(String[] args) throws Exception{
        String input = "aa";
        String algorithm = "MD5";

        // sha1 可以實作秒傳功能

        String sha1 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-1");
        System.out.println(sha1);

        String sha512 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-512");
        System.out.println(sha512);

        String md5 = getDigest("aa", "MD5");
        System.out.println(md5);

        String md51 = getDigest("aa ", "MD5");
        System.out.println(md51);
    }

    private static String getDigestFile(String filePath, String algorithm) throws Exception{
        FileInputStream fis = new FileInputStream(filePath);
        int len;
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ( (len =  fis.read(buffer))!=-1){
            baos.write(buffer,0,len);
        }
        // 獲取訊息摘要物件
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 獲取訊息摘要
        byte[] digest = messageDigest.digest(baos.toByteArray());
        System.out.println("密文的位元組長度:"+digest.length);
        return toHex(digest);
    }

    private static String getDigest(String input, String algorithm) throws Exception{
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        byte[] digest = messageDigest.digest(input.getBytes());
        System.out.println("密文的位元組長度:"+digest.length);
        return toHex(digest);
    }

    private static String toHex(byte[] digest) {
        //        System.out.println(new String(digest));
        // 訊息摘要進行表示的時候,是用16進制進行表示
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            // 轉成16進制

            String s = Integer.toHexString(b & 0xff);
            // 保持資料的完整性,前面不夠的用0補齊
            if (s.length()==1){
                s="0"+s;
            }
            sb.append(s);
        }
        System.out.println("16進制資料的長度:"+ sb.toString().getBytes().length);
        return sb.toString();
    }
}

運行程式 ,獲取 sha-1 和 sha-512 的值:

查看 tomcat 官網上面 sha-1 和 sha-512 的值:

使用 sha-1 演算法,可以實作秒傳功能,不管咱們如何修改檔案的名字,最后得到的值是一樣的

總結:

  • MD5演算法 : 摘要結果16個位元組, 轉16進制后32個位元組
  • SHA1演算法 : 摘要結果20個位元組, 轉16進制后40個位元組
  • SHA256演算法 : 摘要結果32個位元組, 轉16進制后64個位元組
  • SHA512演算法 : 摘要結果64個位元組, 轉16進制后128個位元組

1.4 非對稱加密

簡介:

① 非對稱加密演算法又稱現代加密演算法,

② 非對稱加密是計算機通信安全的基石,保證了加密資料不會被破解,

③ 與對稱加密演算法不同,非對稱加密演算法需要兩個密鑰:公開密鑰(publickey) 和私有密(privatekey)

④ 公開密鑰和私有密鑰是一對

⑤ 如果用公開密鑰對資料進行加密,只有用對應的私有密鑰才能解密,

⑥ 如果用私有密鑰對資料進行加密,只有用對應的公開密鑰才能解密,

⑦ 因為加密和解密使用的是兩個不同的密鑰,所以這種演算法叫作非對稱加密演算法,

示例:

  • 首先生成密鑰對, 公鑰為(5,14), 私鑰為(11,14)
  • 現在A希望將原文2發送給B
  • A使用公鑰加密資料. 2的5次方mod 14 = 4 , 將密文4發送給B
  • B使用私鑰解密資料. 4的11次方mod14 = 2, 得到原文2
    特點:
  • 加密和解密使用不同的密鑰
  • 如果使用私鑰加密, 只能使用公鑰解密
  • 如果使用公鑰加密, 只能使用私鑰解密
  • 處理資料的速度較慢, 因為安全級別高
    常見演算法:
  • RSA
  • ECC

1.4.1 生成公鑰和私鑰

public class RSAdemo {
    public static void main(String[] args) throws Exception {
      
        // 加密演算法
        String algorithm = "RSA";
        //  創建密鑰對生成器物件
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        // 生成密鑰對
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 生成私鑰
        PrivateKey privateKey = keyPair.getPrivate();
        // 生成公鑰
        PublicKey publicKey = keyPair.getPublic();
        // 獲取私鑰位元組陣列
        byte[] privateKeyEncoded = privateKey.getEncoded();
        // 獲取公鑰位元組陣列
        byte[] publicKeyEncoded = publicKey.getEncoded();
        // 對公私鑰進行base64編碼
        String privateKeyString = Base64.encode(privateKeyEncoded);
        String publicKeyString = Base64.encode(publicKeyEncoded);
        // 列印私鑰
        System.out.println(privateKeyString);
        // 列印公鑰
        System.out.println(publicKeyString);
    }
}

運行程式:先列印的是私鑰 , 后面列印的是公鑰,

1.4.2 私鑰加密

public class RSAdemo {
    public static void main(String[] args) throws Exception {
        String input = "硅谷";
        // 加密演算法
        String algorithm = "RSA";
        //  創建密鑰對生成器物件
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        // 生成密鑰對
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 生成私鑰
        PrivateKey privateKey = keyPair.getPrivate();
        // 生成公鑰
        PublicKey publicKey = keyPair.getPublic();
        // 獲取私鑰位元組陣列
        byte[] privateKeyEncoded = privateKey.getEncoded();
        // 獲取公鑰位元組陣列
        byte[] publicKeyEncoded = publicKey.getEncoded();
        // 對公私鑰進行base64編碼
        String privateKeyString = Base64.encode(privateKeyEncoded);
        String publicKeyString = Base64.encode(publicKeyEncoded);


        // 創建加密物件
        // 引數表示加密演算法
        Cipher cipher = Cipher.getInstance(algorithm);
        // 初始化加密
        // 第一個引數:加密的模式
        // 第二個引數:使用私鑰進行加密
        cipher.init(Cipher.ENCRYPT_MODE,privateKey);
        // 私鑰加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        System.out.println(Base64.encode(bytes));
       
    }
}

運行結果:

1.4.3 私鑰加密私鑰解密

public class RSAdemo {
    public static void main(String[] args) throws Exception {
        String input = "硅谷";
        // 加密演算法
        String algorithm = "RSA";
        //  創建密鑰對生成器物件
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        // 生成密鑰對
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 生成私鑰
        PrivateKey privateKey = keyPair.getPrivate();
        // 生成公鑰
        PublicKey publicKey = keyPair.getPublic();
        // 獲取私鑰位元組陣列
        byte[] privateKeyEncoded = privateKey.getEncoded();
        // 獲取公鑰位元組陣列
        byte[] publicKeyEncoded = publicKey.getEncoded();
        // 對公私鑰進行base64編碼
        String privateKeyString = Base64.encode(privateKeyEncoded);
        String publicKeyString = Base64.encode(publicKeyEncoded);


        // 創建加密物件
        // 引數表示加密演算法
        Cipher cipher = Cipher.getInstance(algorithm);
        // 初始化加密
        // 第一個引數:加密的模式
        // 第二個引數:使用私鑰進行加密
        cipher.init(Cipher.ENCRYPT_MODE,privateKey);
        // 私鑰加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        System.out.println(Base64.encode(bytes));
        // 私鑰進行解密
        cipher.init(Cipher.DECRYPT_MODE,publicKey);
        // 對密文進行解密,不需要使用base64,因為原文不會亂碼
        byte[] bytes1 = cipher.doFinal(bytes);
        System.out.println(new String(bytes1));

    }
}

運行程式 ,因為私鑰加密,只能公鑰解密:

1.4.4 私鑰加密公鑰解密

public class RSAdemo {
    public static void main(String[] args) throws Exception {
        String input = "硅谷";
        // 加密演算法
        String algorithm = "RSA";
        //  創建密鑰對生成器物件
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        // 生成密鑰對
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 生成私鑰
        PrivateKey privateKey = keyPair.getPrivate();
        // 生成公鑰
        PublicKey publicKey = keyPair.getPublic();
        // 獲取私鑰位元組陣列
        byte[] privateKeyEncoded = privateKey.getEncoded();
        // 獲取公鑰位元組陣列
        byte[] publicKeyEncoded = publicKey.getEncoded();
        // 對公私鑰進行base64編碼
        String privateKeyString = Base64.encode(privateKeyEncoded);
        String publicKeyString = Base64.encode(publicKeyEncoded);


        // 創建加密物件
        // 引數表示加密演算法
        Cipher cipher = Cipher.getInstance(algorithm);
        // 初始化加密
        // 第一個引數:加密的模式
        // 第二個引數:使用私鑰進行加密
        cipher.init(Cipher.ENCRYPT_MODE,privateKey);
        // 私鑰加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        System.out.println(Base64.encode(bytes));
        // 私鑰進行解密
        cipher.init(Cipher.DECRYPT_MODE,publicKey);
        // 對密文進行解密,不需要使用base64,因為原文不會亂碼
        byte[] bytes1 = cipher.doFinal(bytes);
        System.out.println(new String(bytes1));

    }
}

運行程式:

1.5 數字簽名

數字簽名(又稱公鑰數字簽名)是只有資訊的發送者才能產生的別人無法偽造的一段數字串,這段數字串同時也是對資訊的發送者發送資訊真實性的一個有效證明,它是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領域的技術來實作的,用于鑒別數字資訊的方法,一套數字簽名通常定義兩種互補的運算,一個用于簽名,另一個用于驗證,數字簽名是非對稱密鑰加密技術與數字摘要技術的應用,

1.5.1 簡單認識

相信我們都寫過信,在寫信的時候落款處總是要留下自己的名字,用來表示寫信的人是誰,我們簽的這個字就是生活中的簽名,
而數字簽名呢?其實也是同樣的道理,他的含義是:在網路中傳輸資料時候,給資料添加一個數字簽名,表示是誰發的資料,而且還能證明資料沒有被篡改,

OK,數字簽名的主要作用就是保證了資料的有效性(驗證是誰發的)和完整性(證明資訊沒有被篡改),下面我們就來好好地看一下他的底層實作原理是什么樣子的,

1.5.2 基本原理

為了理解得清楚,我們通過案例一步一步來講解,話說張三有倆好哥們A、B,由于作業原因,張三和AB寫郵件的時候為了安全都需要加密,于是張三想到了數字簽名:

整個思路是這個樣子的:

第一步:加密采用非對稱加密,張三有三把鑰匙,兩把公鑰,送給朋友,一把私鑰留給自己,

第二步:A或者B寫郵件給張三:A先用公鑰對郵件加密,然后張三收到郵件之后使用私鑰解密,

第三步:張三寫郵件給A或者B:

(1)張三寫完郵件,先用hash函式生成郵件的摘要,附著在文章上面,這就完成了數字簽名,然后張三再使用私鑰加密,就可以把郵件發出去了,

(2)A或者是B收到郵件之后,先把數字簽名取下來,然后使用自己的公鑰解密即可,這時候取下來的數字簽名中的摘要若和張三的一致,那就認為是張三發來的,再對信件本身使用Hash函式,將得到的結果,與上一步得到的摘要進行對比,如果兩者一致,就證明這封信未被修改過,

上面的流程我們使用一張圖來演示一下:

首先把公鑰送給朋友A和B:

還有就是最后一個比較麻煩的,張三給A或者B發郵件:

1.5.3 數字證書

上面提到我們對簽名進行驗證時,需要用到公鑰,如果公鑰是偽造的,那我們無法驗證數字簽名了,也就根本不可能從數字簽名確定對方的合法性了,這時候證書就閃亮登場了,我們可能都有考各種證書的經歷,比如說普通話證書,四六級證書等等,但是歸根結底,到任何場合我們都能拿出我們的證書來證明自己確實已經考過了普通話,考過了四六級,這里的證書也是同樣的道理,

如果不理解證書的作用,我們可以舉一個例子,比如說我們的畢業證書,任何公司都會承認,為什么會承認?因為那是國家發得,大家都信任國家,也就是說只要是國家的認證機構,我們都信任它是合法的,

那么這個證書是如何生成的呢?我們再來看一張圖:

此時即使張三的朋友A把公鑰弄錯了,張三也可以通過這個證書驗證,

1.5.4 代碼實作

import java.security.*;
import com.sun.org.apache.xml.internal.security.utils.Base64;
public class SignatureDemo {
    public static void main(String[] args) throws Exception {
        String a = "123";

        PublicKey publicKey = RsaDemo.loadPublicKeyFromFile("RSA", "a.pub");
        PrivateKey privateKey = RsaDemo.loadPrivateKeyFromFile("RSA", "a.pri");

        String signaturedData = https://www.cnblogs.com/xhj928675426/p/getSignature(a, "sha256withrsa", privateKey);

        boolean b = verifySignature(a, "sha256withrsa", publicKey, signaturedData);

    }

    /**
     * 生成簽名
     *
     * @param input      : 原文
     * @param algorithm  : 演算法
     * @param privateKey : 私鑰
     * @return : 簽名
     * @throws Exception
     */
    private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception {
        // 獲取簽名物件
        Signature signature = Signature.getInstance(algorithm);
        // 初始化簽名
        signature.initSign(privateKey);
        // 傳入原文
        signature.update(input.getBytes());
        // 開始簽名
        byte[] sign = signature.sign();
        // 對簽名資料進行Base64編碼
        return Base64.encode(sign);
    }

    /**
     * 校驗簽名
     *
     * @param input          : 原文
     * @param algorithm      : 演算法
     * @param publicKey      : 公鑰
     * @param signaturedData : 簽名
     * @return : 資料是否被篡改
     * @throws Exception
     */
    private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signaturedData) throws Exception {
        // 獲取簽名物件
        Signature signature = Signature.getInstance(algorithm);
        // 初始化簽名
        signature.initVerify(publicKey);
        // 傳入原文
        signature.update(input.getBytes());
        // 校驗資料
        return signature.verify(Base64.decode(signaturedData));

    }

}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/628.html

標籤:區塊鏈

上一篇:密碼學DAY1_02

下一篇:NTP時鐘服務器的特點(京準電子)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • JAVA使用 web3j 進行token轉賬

    最近新學習了下區塊鏈這方面的知識,所學不多,給大家分享下。 # 1. 關于web3j web3j是一個高度模塊化,反應性,型別安全的Java和Android庫,用于與智能合約配合并與以太坊網路上的客戶端(節點)集成。 # 2. 準備作業 jdk版本1.8 引入maven <dependency> < ......

    uj5u.com 2020-09-10 03:03:06 more
  • 以太坊智能合約開發框架Truffle

    前言 部署智能合約有多種方式,命令列的瀏覽器的渠道都有,但往往跟我們程式員的風格不太相符,因為我們習慣了在IDE里寫了代碼然后打包運行看效果。 雖然現在IDE中已經存在了Solidity插件,可以撰寫智能合約,但是部署智能合約卻要另走他路,沒辦法進行一個快捷的部署與測驗。 如果團隊管理的區塊節點多、 ......

    uj5u.com 2020-09-10 03:03:12 more
  • 谷歌二次驗證碼成為區塊鏈專用安全碼,你怎么看?

    前言 谷歌身份驗證器,前些年大家都比較陌生,但隨著國內互聯網安全的加強,它越來越多地出現在大家的視野中。 比較廣泛接觸的人群是國際3A游戲愛好者,游戲盜號現象嚴重+國外賬號安全應用廣泛,這類游戲一般都會要求用戶系結名為“兩步驗證”、“雙重驗證”等,平臺一般都推薦用谷歌身份驗證器。 后來區塊鏈業務風靡 ......

    uj5u.com 2020-09-10 03:03:17 more
  • 密碼學DAY1

    目錄 ##1.1 密碼學基本概念 密碼在我們的生活中有著重要的作用,那么密碼究竟來自何方,為何會產生呢? 密碼學是網路安全、資訊安全、區塊鏈等產品的基礎,常見的非對稱加密、對稱加密、散列函式等,都屬于密碼學范疇。 密碼學有數千年的歷史,從最開始的替換法到如今的非對稱加密演算法,經歷了古典密碼學,近代密 ......

    uj5u.com 2020-09-10 03:03:50 more
  • 密碼學DAY1_02

    目錄 ##1.1 ASCII編碼 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際標準ISO/IE ......

    uj5u.com 2020-09-10 03:04:50 more
  • 密碼學DAY2

    ##1.1 加密模式 加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html ECB ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進 ......

    uj5u.com 2020-09-10 03:05:42 more
  • NTP時鐘服務器的特點(京準電子)

    NTP時鐘服務器的特點(京準電子) NTP時鐘服務器的特點(京準電子) 京準電子官V——ahjzsz 首先對時間同步進行了背景介紹,然后討論了不同的時間同步網路技術,最后指出了建立全球或區域時間同步網存在的問題。 一、概 述 在通信領域,“同步”概念是指頻率的同步,即網路各個節點的時鐘頻率和相位同步 ......

    uj5u.com 2020-09-10 03:05:47 more
  • 標準化考場時鐘同步系統推進智能化校園建設

    標準化考場時鐘同步系統推進智能化校園建設 標準化考場時鐘同步系統推進智能化校園建設 安徽京準電子科技官微——ahjzsz 一、背景概述隨著教育事業的快速發展,學校建設如雨后春筍,隨之而來的學校教育、管理、安全方面的問題成了學校管理人員面臨的最大的挑戰,這些問題同時也是學生家長所擔心的。為了讓學生有更 ......

    uj5u.com 2020-09-10 03:05:51 more
  • 位元幣入門

    引言 位元幣基本結構 位元幣基礎知識 1)哈希演算法 2)非對稱加密技術 3)數字簽名 4)MerkleTree 5)哪有位元幣,有的是UTXO 6)位元幣挖礦與共識 7)區塊驗證(共識) 總結 引言 上一篇我們已經知道了什么是區塊鏈,此篇說一下區塊鏈的第一個應用——位元幣。其實先有位元幣,后有的區塊 ......

    uj5u.com 2020-09-10 03:06:15 more
  • 北斗對時服務器(北斗對時設備)電力系統應用

    北斗對時服務器(北斗對時設備)電力系統應用 北斗對時服務器(北斗對時設備)電力系統應用 京準電子科技官微(ahjzsz) 中國北斗衛星導航系統(英文名稱:BeiDou Navigation Satellite System,簡稱BDS),因為是目前世界范圍內唯一可以大面積提供免費定位服務的系統,所以 ......

    uj5u.com 2020-09-10 03:06:20 more
最新发布
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:46:47 more
  • Hyperledger Fabric 使用 CouchDB 和復雜智能合約開發

    在上個實驗中,我們已經實作了簡單智能合約實作及客戶端開發,但該實驗中智能合約只有基礎的增刪改查功能,且其中的資料管理功能與傳統 MySQL 比相差甚遠。本文將在前面實驗的基礎上,將 Hyperledger Fabric 的默認資料庫支持 LevelDB 改為 CouchDB 模式,以實作更復雜的資料... ......

    uj5u.com 2023-04-16 07:28:31 more
  • .NET Core 波場鏈離線簽名、廣播交易(發送 TRX和USDT)筆記

    Get Started NuGet You can run the following command to install the Tron.Wallet.Net in your project. PM> Install-Package Tron.Wallet.Net 配置 public reco ......

    uj5u.com 2023-04-14 08:08:00 more
  • DKP 黑客分析——不正確的代幣對比率計算

    概述: 2023 年 2 月 8 日,針對 DKP 協議的閃電貸攻擊導致該協議的用戶損失了 8 萬美元,因為 execute() 函式取決于 USDT-DKP 對中兩種代幣的余額比率。 智能合約黑客概述: 攻擊者的交易:0x0c850f,0x2d31 攻擊者地址:0xF38 利用合同:0xf34ad ......

    uj5u.com 2023-04-07 07:46:09 more
  • Defi開發簡介

    Defi開發簡介 介紹 Defi是去中心化金融的縮寫, 是一項旨在利用區塊鏈技術和智能合約創建更加開放,可訪問和透明的金融體系的運動. 這與傳統金融形成鮮明對比,傳統金融通常由少數大型銀行和金融機構控制 在Defi的世界里,用戶可以直接從他們的電腦或移動設備上訪問廣泛的金融服務,而不需要像銀行或者信 ......

    uj5u.com 2023-04-05 08:01:34 more
  • solidity簡單的ERC20代幣實作

    // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "hardhat/console.sol"; //ERC20 同質化代幣,每個代幣的本質或性質都是相同 //ETH 是原生代幣,它不是ERC20代幣, ......

    uj5u.com 2023-03-21 07:56:29 more
  • solidity 參考型別修飾符memory、calldata與storage 常量修飾符C

    在solidity語言中 參考型別修飾符(參考型別為存盤空間不固定的數值型別) memory、calldata與storage,它們只能修飾參考型別變數,比如字串、陣列、位元組等... memory 適用于方法傳參、返參或在方法體內使用,使用完就會清除掉,釋放記憶體 calldata 僅適用于方法傳參 ......

    uj5u.com 2023-03-08 07:57:54 more
  • solidity注解標簽

    在solidity語言中 注釋符為// 注解符為/* 內容*/ 或者 是 ///內容 注解中含有這幾個標簽給予我們使用 @title 一個應該描述合約/介面的標題 contract, library, interface @author 作者的名字 contract, library, interf ......

    uj5u.com 2023-03-08 07:57:49 more
  • 評價指標:相似度、GAS消耗

    【代碼注釋自動生成方法綜述】 這些評測指標主要來自機器翻譯和文本總結等研究領域,可以評估候選文本(即基于代碼注釋自動方法而生成)和參考文本(即基于手工方式而生成)的相似度. BLEU指標^[^?88^^?^]^:其全稱是bilingual evaluation understudy.該指標是最早用于 ......

    uj5u.com 2023-02-23 07:27:39 more
  • 基于NOSTR協議的“公有制”版本的Twitter,去中心化社交軟體Damus

    最近,一個幽靈,Web3的幽靈,在網路游蕩,它叫Damus,這玩意詮釋了什么叫做病毒式營銷,滑稽的是,一個Web3產品卻在Web2的產品鏈上瘋狂傳銷,各方大佬紛紛為其背書,到底發生了什么?Damus的葫蘆里,賣的是什么藥? 注冊和簡單實用 很少有什么產品在用戶注冊環節會有什么噱頭,但Damus確實出 ......

    uj5u.com 2023-02-05 06:48:39 more