[AES symmetric encryption KeyStore uses EhCache]

AES symmetric encryption and KeyStore data storage and reading, EhCache storage information

  • AES symmetric encryption and decryption
  • KEYSTORE store read information
  • KEYSTORE stores and reads key information
  • related import
  • EhCache uses

AES symmetric encryption and decryption

/**
     * AES symmetric encryption, decryption test
     */
    public static void aesTest() {<!-- -->
        String plainText = "TCBJ-SECRET-KEY-ENCODE-DECODE-TEST";
        try {<!-- -->
            // generate secret key
            KeyGenerator keyGenerator = KeyGenerator. getInstance("AES");
            keyGenerator.init(128);
            SecretKey secretKey = keyGenerator. generateKey();

            /**
             * todo
             * Save the secret key according to the business, once the secret key changes, the old content cannot be decrypted
             */

            // encryption
            Cipher cipher = Cipher. getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encrypted = cipher.doFinal(plainText.getBytes());

            // decrypt
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decrypted = cipher.doFinal(encrypted);

            System.out.println("Input:" + plainText);
            System.out.println("Encryption result:" + new String(encrypted));
            System.out.println(decrypted);
            System.out.println("Decryption result:" + new String(decrypted));

        } catch (Exception e) {<!-- -->
            System.out.println("AES encryption and decryption exception");
        }
    }

KEYSTORE store read information

The keystore file here is generated with the command, and the password is defined in the command
If you don’t want to use commands to generate, you can also generate directly in the code
Specific execution path: Open the cmd window under /bin in the JDK installation directory
jceks remember to write correctly

keytool -genkey -alias csdn -keypass 123456 -keyalg RSA -keysize 1024 -validity 3650 -keystore D:/keyStore/test.keystore -storepass 888999 -storetype jceks

store common data

/**
     * keystore file key storage test
     */
    public static void keyStoreTest() {<!-- -->
        FileInputStream inputStream = null;
        OutputStream outputStream = null;
        try {<!-- -->
            // Read the keyStore file and convert it to a keyStore keystore object
            inputStream = new FileInputStream("D:\keyStore\test.keystore");
            // Set certificate type jceks
            KeyStore keyStore = KeyStore. getInstance("jceks");
            // Set the keystore password - the password required to obtain keystore information
            String storepass = "888999";
            keyStore.load(inputStream, storepass.toCharArray());
            inputStream. close();


            // Load the keystore, you can read the existing entries of the keystore, or write new entries
            // Alias - Create the specified alias and password for the file
            String alias = "csdn";
            // Alias password, specify the password of the alias entry - the private key password
            String keypass = "123456";
            KeyStore.ProtectionParameter parameter = new KeyStore.PasswordProtection(keypass.toCharArray());
            KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,parameter);
            PrivateKey myPrivateKey = entry. getPrivateKey();
            System.out.println("The obtained private key is:" + myPrivateKey.toString());

            // Set the secret key information alias desPws and access password decrp pws, and write the storage information desPwd
            String desPwd = "I am the secret key for AES encryption and decryption stored in the keystore 4.0";
            String password = "decryp pws";
            SecretKey mySecretKey = new SecretKeySpec(desPwd. getBytes(),"JKS");
            KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(mySecretKey);
            keyStore.setEntry("desPws", skEntry, new KeyStore.PasswordProtection(password.toCharArray()));
            // store the keystore to the specified output stream, and password protect the integrity
            outputStream = new FileOutputStream("D:\keyStore\test.keystore");
            keyStore.store(outputStream, storepass.toCharArray());
            outputStream. close();
        } catch (Exception e) {<!-- -->
            // todo failed to store keyStore file
        } finally {<!-- -->
            try {<!-- -->
                if (outputStream != null) {<!-- -->
                    outputStream. close();
                }
                if (inputStream != null) {<!-- -->
                    inputStream. close();
                }
            } catch (IOException e) {<!-- -->
                // todo failed to close the file stream
            }
        }
    }

read common data

/**
     * keystore file key extraction test
     */
    public static void keyStoreDecodeTest() {<!-- -->
        String storepass = "888999";
        try {<!-- -->
            FileInputStream inputStream = null;
            // Read the keystore file and convert it to a keystore keystore object
            inputStream = new FileInputStream("D:\keyStore\test.keystore");
            // set certificate type
            KeyStore keyStore = KeyStore. getInstance("jceks");
            // access with keystore password
            keyStore.load(inputStream, storepass.toCharArray());
            inputStream. close();

            // According to the alias, get the password from the certificate and decrypt it
            // keystore.getKey returns the key associated with the given alias, and restores it with the given passphrase
            String password = "decryp pws";
            Key key = keyStore.getKey("desPws",password.toCharArray());
            // key.getEncode returns the key in the basic encoding format, if the key does not support encoding, return null
            // Note that what is stored here is a string, so it needs to be converted according to the encode. If the value stored is the SecretKey, just the key
            System.out.println("The secret key obtained from the certificate is:" + new String(key.getEncoded()));
        } catch (Exception e) {<!-- -->
            // todo exception handling
        }
    }

KEYSTORE stores and reads key information

This is actually similar to storing and reading ordinary data, except that there is one more step to generate a keystore file
When reading, the key is directly the corresponding stored secretKey

 /**
     * AES key object SecretKey is stored in KeyStore
     */
    public static void saveSecretKey2KeyStore() {<!-- -->
        try {<!-- -->
            // generate secret key
            KeyGenerator keyGenerator = KeyGenerator. getInstance("AES");
            keyGenerator.init(128);
            SecretKey secretKey = keyGenerator. generateKey();
            KeyStore keyStore = KeyStore. getInstance("jceks");
            keyStore.load(null,null);
            System.out.println("Saved secret key:" + secretKey);
            // Can store strings or objects
            KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
            // Set the entry name and password
            String entryPwd = "abc";
            keyStore.setEntry("test",secretKeyEntry,new KeyStore.PasswordProtection(entryPwd.toCharArray()));
            FileOutputStream outputStream = new FileOutputStream("D:\keyStore\test2.keystore");
            // Set file access password
            String storepwd = "123456";
            keyStore.store(outputStream,storepwd.toCharArray());
            outputStream. close();
        } catch (Exception e) {<!-- -->
            //todo
        }
    }
 /**
     * Get the AES key object SecretKey from KeyStore
     */
    public static void getSecretKeyFromKeyStore() {<!-- -->
        try {<!-- -->
            String storepass = "123456";
            FileInputStream inputStream = new FileInputStream("D:\keyStore\test2.keystore");
            KeyStore keyStore1 = KeyStore. getInstance("jceks");
            keyStore1.load(inputStream, storepass.toCharArray());
            inputStream. close();
            String password = "abc";
            Key key = keyStore1.getKey("test",password.toCharArray());
            SecretKey keyValue = (SecretKey) key;
            System.out.println("The obtained secret key:" + keyValue);
        } catch (Exception e) {<!-- -->
            //todo
        }
    }

Related import

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;

EhCache usage

  • rely
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>
  • application.properties configuration
spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:ehcache.xml
  • ehcache.xml configuration
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false">
    <!--Cache storage path-->
    <diskStore path="D:\keyStore\"/>
    <defaultCache maxElementsInMemory="10000"
                  eternal="false"
                  timeToIdleSeconds="60"
                  timeToLiveSeconds="60"
                  overflowToDisk="true"
                  maxElementsOnDisk="10000000"
                  diskPersistent="false"
                  diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU" />


    <!--Cache file name, configure multiple different caches to store different data-->
    <cache name="shortlinkPropertiesCache"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="150"
           timeToLiveSeconds="600"
           overflowToDisk="false"
           diskPersistent="false"
           diskExpiryThreadIntervalSeconds="1"
           memoryStoreEvictionPolicy="LRU" />


</ehcache>

        <!--
        Entities to be cached must be serialized
        The following attributes are required:
           name: The name of the Cache, which must be unique (ehcache will put this cache in the HashMap).
           iskStore : Specify the data storage location, you can specify the folder location in the disk
           defaultCache : the default management strategy
           maxElementsInMemory: The maximum number of elements cached in memory.
           maxElementsOnDisk: The maximum number of elements cached on disk, the default value is 0, which means unlimited.
           eternal: Set whether the cached elements will never expire. If true, the cached data is always valid,
                                 If it is false, it must be judged according to timeToIdleSeconds and timeToLiveSeconds.
           overflowToDisk: If the data in memory exceeds the memory limit, whether to cache it on disk.

        The following attributes are optional:
         timeToIdleSeconds: The idle time of the object, which refers to how long the object will become invalid if it is not accessed. Only valid for eternal is false. The default value is 0, which means it can always be accessed.
         timeToLiveSeconds: object survival time, refers to the time required for the object from creation to failure. Only valid for eternal is false. The default value is 0, which means it can always be accessed.
         diskPersistent: Whether to persist on disk. Refers to whether the data is valid after restarting the jvm. The default is false.
         diskExpiryThreadIntervalSeconds: Object detection thread running time interval. How often the thread that identifies the state of the object runs.
         diskSpoolBufferSizeMB: Disk size used by DiskStore, the default value is 30MB. Each cache uses its own DiskStore.
         memoryStoreEvictionPolicy: If the data in memory exceeds the memory limit, the policy when caching to disk. The default value is LRU, optional FIFO, LFU.
         clearOnFlush: Whether to clear when the amount of memory is maximum.

        Three clearing strategies for the cache:
        FIFO, first in first out (first in first out).

        LFU, Less Frequently Used (least used). It means the least frequently used. The cached elements have a hit attribute, and the one with the smallest hit value will be cleared from the cache.

        LRU, Least Recently Used (least recently used). (ehcache default value). The cached elements have a timestamp. When the cache capacity is full and a place needs to be made to cache new elements, the existing cached Elements with timestamps farthest from the current time will be evicted from the cache.


        -->
  • use
import com.***.CacheTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: chen
 * @Date: 2023/7/18 10:09
 */
@RestController
public class test {<!-- -->

    private CacheTestService cacheTestService;
    private static final String SHORTLINKTXQ = "ShortLinkTXQ";

    @Autowired
    public test(CacheTestService cacheTestService) {<!-- -->
        this.cacheTestService = cacheTestService;
    }

    @PostMapping("/addCache")
    public void addCache(){<!-- -->
        String result = cacheTestService.addCache(SHORTLINKTXQ);
        System.out.println("Result:" + result);
    }


    @PostMapping("/deleteCache")
    public void deleteCache() {<!-- -->
        cacheTestService.deleteCache(SHORTLINKTXQ);
    }

}

import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * @Author: chen
 * @Project: member-parent
 * @Date: 2023/7/18 10:38
 */
@Service
@Slf4j
public class CacheTestService {<!-- -->




    @Cacheable(value = "shortlinkPropertiesCache", key = "#code")
    public String addCache(String code) {<!-- -->
        //Using the method marked with @Cacheable, Spring will check whether there is a cache element with the same key in the Cache before each execution
        // If it exists, the method will no longer be executed, but the result will be returned directly from the cache, otherwise it will be executed and the returned result will be stored in the specified cache
        System.out.println("The data returned by the access method");
        // It is fine to directly return objects or object collections, and they can be directly stored in the cache, and can be converted into String data such as JSON if not used
        return "cached content";

    }

    @CacheEvict(value = "shortlinkPropertiesCache", key = "#code")
    public void deleteCache(String code) {<!-- -->
        System.out.println("Delete successfully");
    }

    @CachePut(value = "shortlinkPropertiesCache", key = "#code")
    public void updateCache(String code) {<!-- -->
        //The method marked with @CachePut will not check whether there is a previously executed result in the cache before execution
        // Instead, the method will be executed every time, and the execution result will be stored in the specified cache in the form of key-value pairs

    }
}

Call the interface for the first time (add cache)

The second call to the interface


After calling the delete cache interface, re-call the add cache interface