001/*******************************************************************************
002The MIT License (MIT)
003
004Copyright (c) 2024 KILLCODING.COM
005
006Permission is hereby granted, free of charge, to any person obtaining a copy
007of this software and associated documentation files (the "Software"), to deal
008in the Software without restriction, including without limitation the rights
009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010copies of the Software, and to permit persons to whom the Software is
011furnished to do so, subject to the following conditions:
012
013The above copyright notice and this permission notice shall be included in
014all copies or substantial portions of the Software.
015
016THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
022THE SOFTWARE.
023*****************************************************************************/
024package com.killcoding.tool;
025
026import java.io.ByteArrayInputStream;
027import java.io.ByteArrayOutputStream;
028import java.security.Key;
029import java.security.KeyFactory;
030import java.security.KeyPair;
031import java.security.KeyPairGenerator;
032import java.security.NoSuchAlgorithmException;
033import java.security.PrivateKey;
034import java.security.PublicKey;
035import java.security.SecureRandom;
036import java.security.Security;
037import java.security.spec.AlgorithmParameterSpec;
038import java.security.spec.KeySpec;
039import java.security.spec.PKCS8EncodedKeySpec;
040import java.security.spec.X509EncodedKeySpec;
041
042import javax.crypto.Cipher;
043import javax.crypto.CipherInputStream;
044import javax.crypto.CipherOutputStream;
045import javax.crypto.KeyGenerator;
046import javax.crypto.SecretKey;
047import javax.crypto.SecretKeyFactory;
048import javax.crypto.spec.DESKeySpec;
049import javax.crypto.spec.IvParameterSpec;
050import javax.crypto.spec.SecretKeySpec;
051import java.security.MessageDigest;
052import java.util.Arrays;
053import com.killcoding.file.BaseFile;
054
055/**
056 * This class is support base cipher function
057 * */
058public final class CipherTools {
059    
060    public static byte[] DESEncrypt(String keyText, String ivText, byte[] data) throws Exception {
061                DESKeySpec keySpec = null;
062                AlgorithmParameterSpec iv = null ;
063                SecretKeyFactory keyFactory = null;
064                Key key = null;
065                Cipher cipher = null;
066                keySpec = new DESKeySpec(keyText.getBytes(BaseFile.CHARSET));
067                iv = new IvParameterSpec(ivText.getBytes(BaseFile.CHARSET));
068                keyFactory = SecretKeyFactory.getInstance("DES");
069                key = keyFactory.generateSecret(keySpec);
070                cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
071                cipher.init(Cipher.ENCRYPT_MODE, key, iv);
072                return cipher.doFinal(data);
073    }
074    
075    public static byte[] DESDecrypt(String keyText, String ivText, byte[] encryptData) throws Exception {
076                DESKeySpec keySpec = null;
077                AlgorithmParameterSpec iv = null ;
078                SecretKeyFactory keyFactory = null;
079                Key key = null;
080                Cipher cipher = null;
081                keySpec = new DESKeySpec(keyText.getBytes(BaseFile.CHARSET));
082                iv = new IvParameterSpec(ivText.getBytes(BaseFile.CHARSET));
083                keyFactory = SecretKeyFactory.getInstance("DES");
084                key = keyFactory.generateSecret(keySpec);
085                cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
086                cipher.init(Cipher.DECRYPT_MODE, key, iv);
087                return cipher.doFinal(encryptData);             
088    }
089    
090    public static byte[] _3DESEncrypt(String keyText,String ivText,byte[] data) throws Exception {
091        String Algorithm = "DESede";
092                String TRANS_FORMATION = "DESede/CBC/PKCS5Padding";
093                SecretKey key = null;
094                Cipher cipher = null;
095                IvParameterSpec iv = null;
096                key = new SecretKeySpec(keyText.getBytes(BaseFile.CHARSET), Algorithm);
097                cipher = Cipher.getInstance(TRANS_FORMATION);   
098                iv = new IvParameterSpec(ivText.getBytes(BaseFile.CHARSET));
099                cipher.init(Cipher.ENCRYPT_MODE, key,iv);
100                return cipher.doFinal(data);                    
101    }
102    
103    public static byte[] _3DESDecrypt(String keyText,String ivText,byte[] encryptData) throws Exception {
104        String Algorithm = "DESede";
105                String TRANS_FORMATION = "DESede/CBC/PKCS5Padding";
106                SecretKey key = null;
107                Cipher cipher = null;
108                IvParameterSpec iv = null;
109                key = new SecretKeySpec(keyText.getBytes(BaseFile.CHARSET), Algorithm);
110                cipher = Cipher.getInstance(TRANS_FORMATION);   
111                iv = new IvParameterSpec(ivText.getBytes(BaseFile.CHARSET));
112                cipher.init(Cipher.DECRYPT_MODE, key,iv);
113                return cipher.doFinal(encryptData);             
114    }
115    
116    public static byte[] AESEncrypt(String keyText, byte[] data) throws Exception {
117                SecretKeySpec spec = new SecretKeySpec(generateAESKey(keyText), "AES");
118                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
119                cipher.init(Cipher.ENCRYPT_MODE, spec);
120                return cipher.doFinal(data);
121    }
122    
123    public static byte[] AESDecrypt(String keyText, byte[] encryptData) throws Exception {
124                SecretKeySpec spec = new SecretKeySpec(generateAESKey(keyText), "AES");
125                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
126                cipher.init(Cipher.DECRYPT_MODE, spec);
127                return cipher.doFinal(encryptData);
128    }  
129
130    public static byte[] generateAESKey(String keyText) throws Exception {
131        MessageDigest digest = MessageDigest.getInstance("SHA-256");
132        byte[] hash = digest.digest(keyText.getBytes(BaseFile.CHARSET));
133        return Arrays.copyOf(hash, 16);
134    }
135    
136    public static byte[] RSAPrivateKeyGen(byte[] seed) throws Exception {
137                 String ALOGRITHM = "RSA";
138                 String RANDOM_ALOGRITHM = "SHA1PRNG"; 
139                 KeyPairGenerator generator = null;
140                 KeyPair keyPair = null;
141                 generator = KeyPairGenerator.getInstance(ALOGRITHM);
142                 SecureRandom random = SecureRandom
143                                .getInstance(RANDOM_ALOGRITHM);
144                 random.setSeed(seed);
145                 generator.initialize(1024, random);
146                 keyPair = generator.generateKeyPair(); 
147                 return keyPair.getPrivate().getEncoded();
148    }
149    
150    public static byte[] RSAPublieKeyGen(byte[] seed) throws Exception {
151                 String ALOGRITHM = "RSA";
152                 String RANDOM_ALOGRITHM = "SHA1PRNG"; 
153                 KeyPairGenerator generator = null;
154                 KeyPair keyPair = null;
155                 generator = KeyPairGenerator.getInstance(ALOGRITHM);
156                 SecureRandom random = SecureRandom
157                                .getInstance(RANDOM_ALOGRITHM);
158                 random.setSeed(seed);
159                 generator.initialize(1024, random);
160                 keyPair = generator.generateKeyPair(); 
161                 return keyPair.getPublic().getEncoded();
162    }   
163    
164        public static PublicKey RSAPublicKeyFrom(byte[] keyArray) throws Exception {
165                String ALOGRITHM = "RSA";
166                KeySpec keySpec = new X509EncodedKeySpec(
167                keyArray);
168                KeyFactory keyFactory = KeyFactory.getInstance(ALOGRITHM);
169                return keyFactory.generatePublic(keySpec);
170        }
171
172        public static PrivateKey RSAPrivateKeyFrom(byte[] keyArray) throws Exception {
173                String ALOGRITHM = "RSA";
174                KeySpec keySpec = new PKCS8EncodedKeySpec(keyArray);
175                KeyFactory keyFactory = KeyFactory.getInstance(ALOGRITHM);
176                return keyFactory.generatePrivate(keySpec);
177        }
178    
179        public static byte[] RSAEncrypt(Key key, byte[] data) throws Exception {
180            String ALOGRITHM = "RSA";
181                Cipher cipher = Cipher.getInstance(ALOGRITHM);
182                cipher.init(Cipher.ENCRYPT_MODE, key);
183                ByteArrayOutputStream out = new ByteArrayOutputStream();
184                CipherInputStream cis = new CipherInputStream(
185                                new ByteArrayInputStream(data), cipher);
186                byte[] buffer = new byte[1024];
187                int r;
188                try {
189                        while ((r = cis.read(buffer)) > 0) {
190                                out.write(buffer, 0, r);
191                        }
192                } finally {
193                        cis.close();
194                        out.close();
195                }
196                return out.toByteArray();
197        }    
198        
199        public static byte[] RSADecrypt(Key key, byte[] encryptData) throws Exception {
200            String ALOGRITHM = "RSA";
201                Cipher cipher = Cipher.getInstance(ALOGRITHM);
202                cipher.init(Cipher.DECRYPT_MODE, key);
203                ByteArrayInputStream is = new ByteArrayInputStream(encryptData);
204                ByteArrayOutputStream out = new ByteArrayOutputStream();
205                CipherOutputStream cos = new CipherOutputStream(out, cipher);
206                byte[] buffer = new byte[1024];
207                int r;
208                try {
209                        while ((r = is.read(buffer)) >= 0) {
210                                cos.write(buffer, 0, r);
211                        }
212                } finally {
213                        is.close();
214                        cos.close();
215                        out.close();
216                }
217                return out.toByteArray();
218        }       
219
220}