paulwong

API接口中的敏感数据的加密与解密

签名

为防止request中的json在传输过程中被更改,
  1. 需要在传送双方保存一个字符串sinature-key
  2. 用SHA256 hash请求中的json字符串,结果为hash1
  3. {"payload":hash1}以此为字符和sinature-key用JWS HS256算法进行签名,得到sinature1
  4. 在请求的json中加入字段:"sinature":sinature1
  5. 接收方进行逆过程,验证是否会得到该字符串sinature-key
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.ParseException;
import java.util.Base64;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;

public final class SignatureUtil {
    
    private SignatureUtil() {}
    
    public static byte[] genSignatureKey() {
        
        // Generate random 256-bit (32-byte) shared secret
        SecureRandom random = new SecureRandom();
        byte[] sharedSecret = new byte[32];
        random.nextBytes(sharedSecret);
//        a0a2abd8-6162-41c3-83d6-1cf559b46afc
        
        return sharedSecret;
    }
    
    public static String genSignatureKeyString() {
        return Base64.getEncoder().encodeToString(genSignatureKey());
    }
    
    public static byte[] decodeSignatureKey(String signatureKey) {
        return Base64.getDecoder().decode(signatureKey);
    }
    
    /**
     * P.147
     * sign app_body json string
     * 
     * 
@param content
     * 
@param signatureKey
     * 
@return
     * 
@throws JOSEException
     
*/
    public static String sign(String content, byte[] signatureKey) throws JOSEException {
        // Create HMAC signer
        JWSSigner signer = new MACSigner(signatureKey);

        // Prepare JWS object with "Hello, world!" payload
        JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), new Payload(content));

        // Apply the HMAC
        jwsObject.sign(signer);

        // To serialize to compact form, produces something like
        
// eyJhbGciOiJIUzI1NiJ9.SGVsbG8sIHdvcmxkIQ.onO9Ihudz3WkiauDO2Uhyuz0Y18UASXlSc1eS0NkWyA
        return jwsObject.serialize();
        
    }
    
    public static boolean verify(String content, byte[] signatureKey) {
        
        try {
            verifyAndGet(content, signatureKey);
            
            return true;
        } catch (Exception e){
            return false;
        }
    }
    
    public static String verifyAndGet(String content, byte[] signatureKey) throws ParseException, JOSEException {
        
        // To parse the JWS and verify it, e.g. on client-side
        JWSObject jwsObject = JWSObject.parse(content);
        
        JWSVerifier verifier = new MACVerifier(signatureKey);
        
        jwsObject.verify(verifier);
        
        return jwsObject.getPayload().toString();
    }
    
    public static void main(String [] args) throws JOSEException {
        String content = "Hello, world!";
        String signatureKey = "a0a2abd8-6162-41c3-83d6-1cf559b46afc";
        byte[] signatureKeyByte = signatureKey.getBytes(StandardCharsets.UTF_8);
        byte[] signatureKeyByte2 = genSignatureKey();
        
        System.out.println(sign(content, signatureKeyByte));
        System.out.println(sign(content, signatureKeyByte2));
    }


}


如果有文件传输,需对文件加密:

  1. 每个要传输的文件file,生成唯一的密钥symmetric-key
  2. 用此symmetric-key根据AES-256-CBC算法对文件file进行加密,得到enc-file
  3. 将此symmetric-key用public-key加密得到enc-symmetric-key
  4. 将enc-symmetric-key和enc-file一同放进request中进行传输
  5. 接收方用private-key将enc-symmetric-key解密,得到symmetric-key
  6. 接收方用此symmetric-key解密文件enc-file,即可得到file
import static org.apache.commons.codec.digest.MessageDigestAlgorithms.SHA_256;
import static org.apache.commons.codec.digest.MessageDigestAlgorithms.SHA_512;
import static com.novacredit.mcra.mcracommon.common.util.crypto.PasswordHashUtil.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Properties;

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

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.crypto.stream.CryptoInputStream;
import org.apache.commons.crypto.stream.CryptoOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public final class MyFileUtils {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(MyFileUtils.class);

    public static final String HMAC_SHA_256 = HmacAlgorithms.HMAC_SHA_256.getName();
    
    public static final String TRANSFORM = "AES/CBC/PKCS5Padding";
    
    public static final String ALGORITHM_AES = "AES";
    
    private MyFileUtils() {}

    /**
     * check sum
     * 
     * 
@param file
     * 
@return
     * 
@throws IOException
     
*/
    public static String getFileSHA512(File file) throws IOException {
        return new DigestUtils(SHA_512).digestAsHex(file);
    }

    /**
     * check sum
     * 
     * 
@param file
     * 
@return
     * 
@throws IOException
     
*/
    public static String getFileSHA512Quietly(File file) {
        try {
            return new DigestUtils(SHA_512).digestAsHex(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * check sum for source string
     * 
     * 
@param source
     * 
@return
     * 
@throws IOException
     
*/
    public static String getStringSHA256(String source) throws IOException {
        return new DigestUtils(SHA_256).digestAsHex(source);
    }
    
    @Deprecated
    public static byte[] makeKey(String prf, byte[] pass, byte[] salt, int iter, int len) throws Exception {
        
        byte[] result = new byte[len];
        Mac mac = Mac.getInstance(prf);
        mac.init(new SecretKeySpec(pass, prf));
        byte[] saltcnt = Arrays.copyOf(salt, salt.length + 4);
        
        while ( /* remaining */len > 0) {
            for (int o = saltcnt.length; --o >= saltcnt.length - 4;)
                if (++saltcnt[o] != 0)
                    break;
            byte[] u = saltcnt, x = new byte[mac.getMacLength()];
            for (int i = 1; i <= iter; i++) {
                u = mac.doFinal(u);
                for (int o = 0; o < x.length; o++)
                    x[o] ^= u[o];
            }
            int len2 = Math.min(len, x.length);
            System.arraycopy(x, 0, result, result.length - len, len2);
            len -= len2;
        }
        return result;
    }
    
    /**
     * P.149
     * P.79
     * AES256-CBC
     * 
     * 
@param inFilePath
     * 
@param outFilePath
     * 
@param symmetricKey
     * 
@throws Exception
     
*/
    public static void encryptFile(String inFilePath, String outFilePath, String symmetricKey) throws Exception {
        
        char[] pass = symmetricKey.toCharArray();
        byte[] salt = (new SecureRandom()).generateSeed(8);
//        byte[] derive = makeKey(HMAC_SHA_256, pass, salt, PBKDF2_ITERATIONS, SALT_BYTE_SIZE);
        byte[] derive = PasswordHashUtil.pbkdf2(pass, salt, PBKDF2_ITERATIONS, SALT_BYTE_SIZE);
        
        Cipher cipher = Cipher.getInstance(TRANSFORM);
        
        try (
            FileInputStream fis = new FileInputStream(inFilePath);
            FileOutputStream fos = new FileOutputStream(outFilePath);
            CipherOutputStream cos = new CipherOutputStream(fos, cipher);
        ){
            
            //  key is first 32, IV is last 16
            cipher.init(
                      Cipher.ENCRYPT_MODE, 
                      new SecretKeySpec(derive, 0, 32, ALGORITHM_AES), 
                      new IvParameterSpec(derive, 32, 16)
                   );
            
            fos.write("Salted__".getBytes(StandardCharsets.UTF_8));
            fos.write(salt);
            
            
            int b;
            byte[] d = new byte[8];
            
            while ((b = fis.read(d)) != -1) {
                cos.write(d, 0, b);
            }
            cos.flush();
//            cos.close();
//            fis.close();
        }
        
    }
    
    @Deprecated
    public static void decryptFileOld(String inFilePath, String outFilePath, String symmetricKey) throws Exception {
        
        try (FileOutputStream fos = new FileOutputStream(outFilePath);){
            
            byte[] file = Files.readAllBytes(Paths.get(inFilePath));
            byte[] pass = symmetricKey.getBytes();
            Cipher cipher = Cipher.getInstance(TRANSFORM);
            
            // extract salt and derive 
            byte[] salt = Arrays.copyOfRange(file, 8, 16);
            byte[] derive = makeKey(HMAC_SHA_256, pass, salt, PBKDF2_ITERATIONS, SALT_BYTE_SIZE);
            
            //  key is first 32, IV is last 16
            cipher.init(
                      Cipher.DECRYPT_MODE, 
                      new SecretKeySpec(derive, 0, 32, ALGORITHM_AES), 
                      new IvParameterSpec(derive, 32, 16)
                   );
            
            // remainder of file is ciphertext
//            String contentDecoded = new String(cipher.doFinal(file,16,file.length-16) , StandardCharsets.UTF_8);
            fos.write(cipher.doFinal(file,16,file.length-16));
//            fos.close();
            
        }
        
    }
    
    public static void decryptFile(String inFilePath, String outFilePath, String symmetricKey) throws Exception {
        try(
            FileInputStream fis = new FileInputStream(inFilePath);
            FileOutputStream fos = new FileOutputStream(outFilePath, true);
        ){
            char[] pass = symmetricKey.toCharArray();
            Cipher cipher = Cipher.getInstance(TRANSFORM);
            
            int i=0;
            int b;
            byte[] bytes = new byte[2048];
            while ((b = fis.read(bytes)) != -1) {
            
                byte[] contentBytes = Arrays.copyOf(bytes, b);
                    
                byte[] content = null;
                if(i == 0) {
                    byte[] salt = Arrays.copyOfRange(bytes, 8, 16);
//                    byte[] derive = makeKey(HMAC_SHA_256, pass, salt, PBKDF2_ITERATIONS, SALT_BYTE_SIZE);
                    byte[] derive = PasswordHashUtil.pbkdf2(pass, salt, PBKDF2_ITERATIONS, SALT_BYTE_SIZE);
                    cipher.init(
                              Cipher.DECRYPT_MODE, 
                              new SecretKeySpec(derive, 0, 32, ALGORITHM_AES), 
                              new IvParameterSpec(derive, 32, 16)
                           );
                
                    content = cipher.doFinal(contentBytes, 16, contentBytes.length-16); 
                } else {
                    content = cipher.doFinal(contentBytes); 
                }
                fos.write(content);
                fos.flush();
                
                i++;
            }
            
        } catch(Exception e) {
            LOGGER.error(e.getMessage(),e);
            throw e;
        }

    }
    
    private static byte[] getUTF8Bytes(final String input) {
        return input.getBytes(StandardCharsets.UTF_8);
    }
    
    public static void encryptFile2(String inFilePath, String outFilePath, String symmetricKey) throws Exception {
        
        byte [] semmetryKeyByte = getUTF8Bytes(symmetricKey);
        final SecretKeySpec key = new SecretKeySpec(semmetryKeyByte, ALGORITHM_AES);
        final IvParameterSpec iv = new IvParameterSpec(semmetryKeyByte);
        final Properties properties = new Properties();
        
        //Encryption with CryptoOutputStream.
        
        try (
            FileInputStream fis = new FileInputStream(inFilePath);
            FileOutputStream fos = new FileOutputStream(outFilePath);
            CryptoOutputStream cos = new CryptoOutputStream(TRANSFORM, properties, fos, key, iv)
        ) {
            
            byte[] buf = new byte[1024 * 16];
            int len;
            while ((len = fis.read(buf)) != -1) {
                cos.write(buf, 0, len);
            }
            
//            fis.close();
            cos.flush();
        }
    }
    
    public static void decryptFile2(String inFilePath, String outFilePath, String semmetryKey) throws Exception {
        
        byte [] semmetryKeyByte = getUTF8Bytes(semmetryKey);
        final SecretKeySpec secretKey = new SecretKeySpec(semmetryKeyByte, ALGORITHM_AES);
        final IvParameterSpec initializationVector = new IvParameterSpec(semmetryKeyByte);
        Properties properties = new Properties();
        
        try (
            FileInputStream fis = new FileInputStream(inFilePath);
            FileOutputStream fos = new FileOutputStream(outFilePath);
            CryptoInputStream cis = new CryptoInputStream(TRANSFORM, properties, fis, secretKey,
                                        initializationVector);
        ){
            
            byte[] buf = new byte[1024 * 16];
            int len;
            while ((len = cis.read(buf)) != -1) {
               fos.write(buf, 0, len);
            }
            
//            cis.close();
            fos.flush();
            
        }
        
    }

}



import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.StringUtils;

public class SymmetricKeyUtil {
    
    private SymmetricKeyUtil() {}
    
    /**
     * P.79
     * 
     * 
@param symmetricKey
     * 
@param publicKey
     * 
@return
     * 
@throws Exception
     
*/
    public static String encryptWithPublicKey(String symmetricKey, PublicKey publicKey) throws Exception {
        
        // --- encrypt given algorithm string
        Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
        oaepFromAlgo.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = oaepFromAlgo.doFinal(StringUtils.getBytesUtf8(symmetricKey));
        
        return Base64.getEncoder().encodeToString(result);
    }
    
    public static String decryptWithPrivateKey(String symmetricKey, PrivateKey privateKey) throws Exception {
        
        // --- encrypt given algorithm string
        Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
//        OAEPParameterSpec oaepParams = 
//                new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSource.PSpecified.DEFAULT);
//        oaepFromAlgo.init(Cipher.DECRYPT_MODE, privateKey, oaepParams);
        oaepFromAlgo.init(Cipher.DECRYPT_MODE, privateKey);
        
        byte[] decodedContent = Base64.getDecoder().decode(symmetricKey);
        byte[] result = oaepFromAlgo.doFinal(decodedContent);
        
        return StringUtils.newStringUtf8(result);
        
    }

}


import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public class PasswordHashUtil {
    
    public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA256";
    
    public static final int PBKDF2_ITERATIONS = 10000;
    
    public static final int HASH_BYTE_SIZE = 48;
    
    public static final int SALT_BYTE_SIZE = 48;
    
    private PasswordHashUtil() {}

    /**
     * Computes the PBKDF2 hash of a password.
     * 
     * 
@param password
     *            the password to hash.
     * 
@param salt
     *            the salt
     * 
@param iterations
     *            the iteration count (slowness factor)
     * 
@param bytes
     *            the length of the hash to compute in bytes
     * 
@return the PBDKF2 hash of the password
     
*/
    protected static byte[] pbkdf2(final char[] password, final byte[] salt, final int iterations, final int bytes)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        
        final PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
        final SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
        return skf.generateSecret(spec).getEncoded();
    }

    /**
     * Returns a salted PBKDF2 hash of the password.
     * 
     * 
@param password
     *            the password to hash
     * 
@return a salted PBKDF2 hash of the password
     
*/
    public static byte[] createHash(final char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException {
        
        // Generate a random salt
        final SecureRandom random = new SecureRandom();
        final byte[] salt = new byte[SALT_BYTE_SIZE];
        random.nextBytes(salt);

        // Hash the password
        final byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
        // format iterations:salt:hash
//        return PBKDF2_ITERATIONS + ":" + toEncoding(salt) + ":" + toEncoding(hash);
        return hash;
    }

}



import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public final class PasswordGenerator {

    private static final String LOWER = "abcdefghijklmnopqrstuvwxyz";
    private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String DIGITS = "0123456789";
    private static final String PUNCTUATION = "!@#$%&*()_+-=[]|,./?><";
    private boolean useLower;
    private boolean useUpper;
    private boolean useDigits;
    private boolean usePunctuation;

    private PasswordGenerator() {
        throw new UnsupportedOperationException("Empty constructor is not supported.");
    }

    private PasswordGenerator(PasswordGeneratorBuilder builder) {
        this.useLower = builder.useLower;
        this.useUpper = builder.useUpper;
        this.useDigits = builder.useDigits;
        this.usePunctuation = builder.usePunctuation;
    }

    public static class PasswordGeneratorBuilder {

        private boolean useLower;
        private boolean useUpper;
        private boolean useDigits;
        private boolean usePunctuation;

        public PasswordGeneratorBuilder() {
            this.useLower = false;
            this.useUpper = false;
            this.useDigits = false;
            this.usePunctuation = false;
        }

        /**
         * Set true in case you would like to include lower characters
         * (abcxyz). Default false.
         *
         * 
@param useLower true in case you would like to include lower
         * characters (abcxyz). Default false.
         * 
@return the builder for chaining.
         
*/
        public PasswordGeneratorBuilder useLower(boolean useLower) {
            this.useLower = useLower;
            return this;
        }

        /**
         * Set true in case you would like to include upper characters
         * (ABCXYZ). Default false.
         *
         * 
@param useUpper true in case you would like to include upper
         * characters (ABCXYZ). Default false.
         * 
@return the builder for chaining.
         
*/
        public PasswordGeneratorBuilder useUpper(boolean useUpper) {
            this.useUpper = useUpper;
            return this;
        }

        /**
         * Set true in case you would like to include digit characters (123..).
         * Default false.
         *
         * 
@param useDigits true in case you would like to include digit
         * characters (123..). Default false.
         * 
@return the builder for chaining.
         
*/
        public PasswordGeneratorBuilder useDigits(boolean useDigits) {
            this.useDigits = useDigits;
            return this;
        }

        /**
         * Set true in case you would like to include punctuation characters
         * (!@#..). Default false.
         *
         * 
@param usePunctuation true in case you would like to include
         * punctuation characters (!@#..). Default false.
         * 
@return the builder for chaining.
         
*/
        public PasswordGeneratorBuilder usePunctuation(boolean usePunctuation) {
            this.usePunctuation = usePunctuation;
            return this;
        }

        /**
         * Get an object to use.
         *
         * 
@return the {@link gr.idrymavmela.business.lib.PasswordGenerator}
         * object.
         
*/
        public PasswordGenerator build() {
            return new PasswordGenerator(this);
        }
    }

    /**
     * This method will generate a password depending the use* properties you
     * define. It will use the categories with a probability. It is not sure
     * that all of the defined categories will be used.
     *
     * 
@param length the length of the password you would like to generate.
     * 
@return a password that uses the categories you define when constructing
     * the object with a probability.
     
*/
    public String generate(int length) {
        // Argument Validation.
        if (length <= 0) {
            return "";
        }

        // Variables.
        StringBuilder password = new StringBuilder(length);
        Random random = new Random(System.nanoTime());

        // Collect the categories to use.
        List<String> charCategories = new ArrayList<>(4);
        if (useLower) {
            charCategories.add(LOWER);
        }
        if (useUpper) {
            charCategories.add(UPPER);
        }
        if (useDigits) {
            charCategories.add(DIGITS);
        }
        if (usePunctuation) {
            charCategories.add(PUNCTUATION);
        }

        // Build the password.
        for (int i = 0; i < length; i++) {
            String charCategory = charCategories.get(random.nextInt(charCategories.size()));
            int position = random.nextInt(charCategory.length());
            password.append(charCategory.charAt(position));
        }
        return new String(password);
    }
    
    public static String genDefaultPassword() {
        return new PasswordGeneratorBuilder()
                        .useDigits(true)
                        .usePunctuation(true)
                        .useUpper(true)
                        .useLower(true)
                        .build()
                        .generate(16);
    }
    
    public static String genDefault32Password() {
        return new PasswordGeneratorBuilder()
                        .useDigits(true)
                        .usePunctuation(true)
                        .useUpper(true)
                        .useLower(true)
                        .build()
                        .generate(32);
    }
    
    public static void main(String [] args) {
        String password = new PasswordGeneratorBuilder()
                                .useDigits(true)
                                .usePunctuation(true)
                                .useUpper(true)
                                .useLower(true)
                                .build()
                                .generate(8);
        System.out.println(password);
    } 
}

单元测试



import java.io.File;

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.novacredit.mcra.democrpcp.test.base.AbstractTestApp;
import com.novacredit.mcra.mcracommon.common.util.crypto.MyFileUtils;
import com.novacredit.mcra.mcracommon.common.util.crypto.PasswordGenerator;

public class EncryptFileTest {
    
    private String inputFilePath = AbstractTestApp.getAbsolutePath(
                "src/test/resources/KCLO_WS01_20210531_103933_ENQ.zip");
    
    private String encryptFilePath = inputFilePath.replace(".zip", ".enc.zip");
    
    private String password = PasswordGenerator.genDefaultPassword();
    
    private String decryptFilePath = inputFilePath.replace(".zip", ".dec.zip");
    
    @BeforeEach
    public void deleteFile() {
        FileUtils.deleteQuietly(new File(encryptFilePath));
        FileUtils.deleteQuietly(new File(decryptFilePath));
    }
    
    @Test
    public void testEncryptFile() throws Exception {
        
        MyFileUtils.encryptFile(inputFilePath, encryptFilePath, password);
        
        MyFileUtils.decryptFile(encryptFilePath, decryptFilePath, password);
        
        
    }
    
    @Test
    public void testEncryptFile2() throws Exception {
        
        MyFileUtils.encryptFile2(inputFilePath, encryptFilePath, password);

        MyFileUtils.decryptFile2(encryptFilePath, decryptFilePath, password);
        
//        FileUtils.deleteQuietly(new File());
        
    }

}


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Base64;

import org.junit.jupiter.api.Test;

import com.nimbusds.jose.JOSEException;
import com.novacredit.mcra.mcracommon.common.util.crypto.PasswordGenerator;
import com.novacredit.mcra.mcracommon.common.util.crypto.SignatureUtil;

public class SignatureUtilTest {
    
    private String content = "Hello, world!";

    @Test
    public void test1() throws JOSEException, ParseException{
        
//        String signatureKey = "a0a2abd8-6162-41c3-83d6-1cf559b46afc";
        String signatureKey = PasswordGenerator.genDefault32Password();
//        String signatureKey = SignatureUtil.genSignatureKeyString();
        System.out.println(signatureKey);
        byte[] signatureKeyByte = signatureKey.getBytes(StandardCharsets.UTF_8);
        
        String result = SignatureUtil.sign(content, signatureKeyByte);
        System.out.println(result);
        
        assertTrue(SignatureUtil.verify(result, signatureKeyByte));
        assertEquals(content, SignatureUtil.verifyAndGet(result, signatureKeyByte));
    }
    
    @Test
    public void test2() throws JOSEException, ParseException{
        
        byte[] signatureKeyByte = SignatureUtil.genSignatureKey();
        
        String signatureKeyString = Base64.getEncoder().encodeToString(signatureKeyByte);
        byte [] decodeSignatureKeyByte = SignatureUtil.decodeSignatureKey(signatureKeyString);
        System.out.println("signatureKeyByte == decodeSignatureKeyByte ? " + Arrays.equals(signatureKeyByte, decodeSignatureKeyByte));
        
        String result = SignatureUtil.sign(content, signatureKeyByte);
        System.out.println(result);
        
        assertTrue(SignatureUtil.verify(result, signatureKeyByte));
        assertEquals(content, SignatureUtil.verifyAndGet(result, signatureKeyByte));
        
    }

}

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

import org.junit.jupiter.api.Test;

import com.novacredit.mcra.mcracommon.common.util.crypto.PublicCertificateUtil;
import com.novacredit.mcra.mcracommon.common.util.crypto.SymmetricKeyUtil;

public class SymmetricKeyUtilTest {
    
    @Test
    public void test1() throws Exception {
        
        KeyPair keyPair = PublicCertificateUtil.genKeyPair();
        
        String privateKeyString = PublicCertificateUtil.keyToBase64String(keyPair.getPrivate());
        String publicKeyString = PublicCertificateUtil.keyToBase64String(keyPair.getPublic());
        
        System.out.println(privateKeyString);
        System.out.println(publicKeyString);
        
        String content = "Hello World.";
        
        PrivateKey privateKey = PublicCertificateUtil.genPrivateKey(privateKeyString);
        PublicKey  publicKey  = PublicCertificateUtil.genPublicKey(publicKeyString);
        
        String encryptResult = SymmetricKeyUtil.encryptWithPublicKey(content, publicKey);
        String decryptResult = SymmetricKeyUtil.decryptWithPrivateKey(encryptResult, privateKey);
        
        assertEquals(decryptResult, content);
    }

}


posted on 2022-05-11 14:37 paulwong 阅读(942) 评论(0)  编辑  收藏 所属分类: J2SE


只有注册用户登录后才能发表评论。


网站导航: