Come crittografare String in Java

Quello di cui ho bisogno è di crittografare la stringa che verrà mostrata nel codice a barre 2D (PDF-417) in modo che quando qualcuno avrà l’idea di scansionarlo non sarà più leggibile.

Altri requisiti:

  • non dovrebbe essere complicato
  • non dovrebbe essere costituito da RSA, infrastruttura PKI, coppie di chiavi, ecc.

Deve essere abbastanza semplice da sbarazzarsi delle persone che curiosano in giro, e facile da decifrare per le altre aziende interessate a ottenere quei dati. Ci chiamano, noi diciamo loro lo standard o diamo loro una chiave semplice che può essere usata per la decrittazione.

Probabilmente queste aziende potrebbero utilizzare diverse tecnologie, quindi sarebbe opportuno attenersi ad alcuni standard che non sono legati ad alcuna piattaforma o tecnologia speciale.

Che cosa suggerisci? Esiste una class Java che esegue encrypt () decrypt () senza molte complicazioni nel raggiungimento di elevati standard di sicurezza?

Consiglierei di usare un cypher simmetrico standard ampiamente disponibile come DES , 3DES o AES . Anche se questo non è l’algoritmo più sicuro, ci sono un sacco di implementazioni e basta dare la chiave a chiunque debba decifrare le informazioni nel codice a barre. javax.crypto.Cipher è ciò con cui vuoi lavorare qui.

Supponiamo che i byte da crittografare siano in

byte[] input; 

Successivamente, avrai bisogno della chiave e dei byte vettoriali di inizializzazione

 byte[] keyBytes; byte[] ivBytes; 

Ora puoi inizializzare il Cipher per l’algoritmo che selezioni:

 // wrap key data in Key/IV specs to pass to cipher SecretKeySpec key = new SecretKeySpec(keyBytes, "DES"); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); // create the cipher with the algorithm you choose // see javadoc for Cipher class for more info, eg Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 

La crittografia sarebbe andata così:

 cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); byte[] encrypted= new byte[cipher.getOutputSize(input.length)]; int enc_len = cipher.update(input, 0, input.length, encrypted, 0); enc_len += cipher.doFinal(encrypted, enc_len); 

E la decifrazione come questa:

 cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); byte[] decrypted = new byte[cipher.getOutputSize(enc_len)]; int dec_len = cipher.update(encrypted, 0, enc_len, decrypted, 0); dec_len += cipher.doFinal(decrypted, dec_len); 

Questa è la prima pagina che appare tramite Google e le vulnerabilità della sicurezza in tutte le implementazioni mi fanno rabbrividire, quindi sto postando questo per aggiungere informazioni sulla crittografia per gli altri come è stato 7 anni dal post originale. Ho conseguito un master in ingegneria informatica e ho dedicato molto tempo allo studio e all’apprendimento della crittografia, quindi sto lanciando i miei due centesimi per rendere Internet un posto più sicuro.

Inoltre, tieni presente che molte implementazioni potrebbero essere sicure per una determinata situazione, ma perché usarle e potenzialmente commettere un errore accidentalmente? Usa gli strumenti più potenti che hai a disposizione a meno che tu non abbia una ragione specifica per non farlo. In generale, consiglio vivamente di usare una biblioteca e di tenermi lontano dai dettagli nitidi se ansible.

AGGIORNAMENTO 4/5/18: Ho riscritto alcune parti per renderle più semplici da capire e ho modificato la libreria consigliata da Jasypt alla nuova libreria di Google Tink , raccomanderei di rimuovere completamente Jasypt da una configurazione esistente.

Prefazione

Illustrerò qui di seguito le basi della crittografia simmetrica sicura e segnalerò gli errori comuni che vedo online quando le persone implementano la crittografia da sole con la libreria standard di Java. Se vuoi semplicemente saltare tutti i dettagli sulla nuova libreria di Google, Tink importa questo nel tuo progetto e usa la modalità AES-GCM per tutte le tue crittografie e sarai sicuro.

Ora se vuoi imparare i dettagli nitidi su come criptare in java, leggi 🙂

Block Ciphers

Per prima cosa devi scegliere una chiave simmetrica Block Cipher. Un cifrario a blocchi è una funzione / programma per computer utilizzata per creare Pseudo-casualità. La pseudo-casualità è una finta casualità che nessun computer diverso da un computer quantistico sarebbe in grado di distinguere tra esso e la casualità reale. Il cifrario a blocchi è come un elemento fondamentale della crittografia e, se utilizzato con diverse modalità o schemi, è ansible creare crittografie.

Ora per quanto riguarda gli algoritmi di cifratura a blocchi disponibili oggi, assicurati di NON ripetere MAI di usare MAI , direi MAI NON usare 3DES . L’unico Block Cipher che persino la versione NSA di Snowden è stata in grado di verificare essere il più vicino ansible allo Pseudo-Random è AES 256 . Esiste anche AES 128, la differenza è che AES 256 funziona in blocchi da 256 bit, mentre AES 128 funziona in 128 blocchi. Tutto sumto AES 128 è considerato sicuro anche se sono stati scoperti alcuni punti deboli, ma 256 è solido come si ottiene.

Fun fact DES è stato rotto dalla NSA quando è stato inizialmente fondato e in realtà è rimasto segreto per alcuni anni e anche se alcune persone sostengono che 3DES è sicuro, ci sono alcuni documenti di ricerca che hanno trovato e analizzato i punti deboli in 3DES .

Modalità di crittografia

La crittografia viene creata quando si prende un codice a blocchi e si utilizza uno schema specifico in modo che la casualità sia combinata con una chiave per creare qualcosa che sia reversibile fintanto che si conosce la chiave. Questo è indicato come una modalità di crittografia.

Ecco un esempio di una modalità di crittografia e la modalità più semplice nota come ECB solo così puoi capire visivamente cosa sta succedendo:

Modalità ECB

Le modalità di crittografia che vedrai più comunemente online sono le seguenti:

ECB CTR, CBC, GCM

Esistono altre modalità al di fuori di quelle elencate e i ricercatori sono sempre alla ricerca di nuove modalità per migliorare i problemi esistenti.

Passiamo ora alle implementazioni e a ciò che è sicuro. MAI usare la BCE non è un problema hide i dati ripetuti come mostrato dal famoso pinguino di Linux . Linux Penguin Example

Quando si implementa in Java, si noti che se si utilizza il seguente codice, la modalità ECB è impostata per impostazione predefinita:

 Cipher cipher = Cipher.getInstance("AES"); 

… PERICOLO QUESTA È UNA VULNERABILITÀ! e sfortunatamente, questo è visto in tutto StackOverflow e online in tutorial ed esempi.

Nonces e IVs

In risposta al problema riscontrato con la modalità ECB, sono stati creati anche nomi noti come IV. L’idea è che generiamo una nuova variabile casuale e la colleghiamo ad ogni crittografia in modo che quando si cifrano due messaggi uguali vengono fuori diversi. La bellezza dietro questo è che un IV o nonce è di dominio pubblico. Ciò significa che un utente malintenzionato può avere accesso a questo, ma fino a quando non ha la chiave, non può fare nulla con quella conoscenza.

Problemi comuni vedrò che le persone imposteranno la IV come un valore statico come nello stesso valore fisso nel loro codice. e qui c’è il trabocchetto delle IV nel momento in cui ne ripeti uno, in realtà comprometti l’intera sicurezza della tua crittografia.

Generazione di un casuale IV

 SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG"); byte[] iv = new byte[cipher.getBlockSize()]; randomSecureRandom.nextBytes(iv); IvParameterSpec ivParams = new IvParameterSpec(iv); 

Nota: SHA1 è rotto, ma non sono riuscito a trovare il modo di implementare correttamente SHA256 in questo caso d’uso, quindi se qualcuno vuole prendere una crepa e aggiornarlo sarebbe fantastico! Inoltre, gli attacchi SHA1 sono ancora non convenzionali in quanto possono richiedere alcuni anni in un enorme cluster da crack. Scopri i dettagli qui.

Implementazione CTR

Non è richiesta alcuna spaziatura per la modalità CTR.

  Cipher cipher = Cipher.getInstance("AES/NoPadding"); 

Implementazione CBC

Se scegli di implementare la modalità CBC, fallo con PKCS7Padding come segue:

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 

Vulnerabilità CBC e CTR e perché è necessario utilizzare GCM

Sebbene alcune altre modalità come CBC e CTR siano sicure, si imbattono nel problema in cui un utente malintenzionato può capovolgere i dati crittografati, modificandone il valore quando decodificato. Quindi diciamo che crittografate un messaggio bancario immaginario “Vendi 100”, il vostro messaggio crittografato appare come questo “eu23ng” l’autore dell’attacco cambia un bit in “eu53ng” e all’improvviso quando decodifica il vostro messaggio, si legge come “Vendi 900”.

Per evitare ciò, la maggior parte di Internet utilizza GCM e, ogni volta che vedi HTTPS, probabilmente utilizzano GCM. GCM firma il messaggio crittografato con un hash e verifica che il messaggio non sia stato modificato utilizzando questa firma.

Eviterei di implementare GCM a causa della sua complessità. Stai meglio usando la nuova libreria Googles Tink perché anche qui, se accidentalmente ripeti un IV, stai compromettendo la chiave nel caso di GCM, che è l’ultimo difetto di sicurezza. Nuovi ricercatori stanno lavorando verso le modalità di crittografia IV ripetute e resistenti dove, anche se ripetete la IV, la chiave non è in pericolo, ma questo deve ancora arrivare al mainstream.

Ora se vuoi implementare GCM, ecco un link per una bella implementazione GCM . Tuttavia, non posso garantire la sicurezza o se è stata implementata correttamente ma ne viene eliminata la base. Nota anche con GCM non c’è padding.

 Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); 

Chiavi contro password

Un’altra nota molto importante è che quando si parla di crittografia, una chiave e una password non sono le stesse cose. Una chiave nella crittografia deve avere una certa quantità di entropia e casualità da essere considerata sicura. Questo è il motivo per cui è necessario assicurarsi di utilizzare le librerie crittografiche appropriate per generare la chiave per te.

Quindi hai davvero due implementazioni che puoi fare qui, il primo è usare il codice trovato su questo thread StackOverflow per la generazione di chiavi casuali . Questa soluzione utilizza un generatore di numeri casuali sicuro per creare una chiave da zero che è ansible utilizzare.

L’altra opzione meno sicura è quella di usare, l’input dell’utente come una password. Il problema come abbiamo discusso è che la password non ha abbastanza entropia, quindi dovremmo usare PBKDF2 , un algoritmo che prende la password e la rafforza. Ecco un’implementazione StackOverflow che mi è piaciuta . Tuttavia la libreria Google Tink ha tutto questo integrato e dovresti approfittarne.

Sviluppatori Android

Un punto importante da sottolineare qui è che il tuo codice Android è reverse engineering e nella maggior parte dei casi lo è anche il codice java. Ciò significa che se si memorizza la password in chiaro nel codice. Un hacker può recuperarlo facilmente. Di solito, per questo tipo di crittografia, si desidera utilizzare la crittografia asimmetrica e così via. Questo è al di fuori dello scopo di questo post, quindi eviterò di immergermi in esso.

Una lettura interessante del 2013 : sottolinea che l’88% delle implementazioni Crypto in Android sono state eseguite in modo improprio.

Pensieri finali

Ancora una volta suggerirei di evitare di implementare direttamente la libreria java per crypto e di usare Google Tink , ti farà risparmiare il mal di testa dato che hanno davvero fatto un buon lavoro implementando correttamente tutti gli algoritmi. E anche allora assicurati di controllare i problemi sollevati sul github di Tink, i popup di vulnerabilità qua e là.

Se avete domande o commenti non esitate a commentare! La sicurezza è in continua evoluzione e devi fare del tuo meglio per tenerti aggiornato 🙂

avvertimento

Non usare questo come una sorta di misura di sicurezza.

Il meccanismo di crittografia in questo post è un blocco One-time, il che significa che la chiave segreta può essere facilmente recuperata da un utente malintenzionato utilizzando 2 messaggi crittografati. XOR 2 messaggi crittografati e ottieni la chiave. Così semplice!

Sottolineato da Moussa


Sto usando Sun’s Base64Encoder / Decoder che si trova in Sun’s JRE, per evitare un altro JAR in lib. Questo è pericoloso dal punto di vista dell’utilizzo di OpenJDK o di altri JRE. Oltre a ciò, c’è un’altra ragione per cui dovrei considerare l’utilizzo di Apons comuni lib con Encoder / Decoder?

 public class EncryptUtils { public static final String DEFAULT_ENCODING = "UTF-8"; static BASE64Encoder enc = new BASE64Encoder(); static BASE64Decoder dec = new BASE64Decoder(); public static String base64encode(String text) { try { return enc.encode(text.getBytes(DEFAULT_ENCODING)); } catch (UnsupportedEncodingException e) { return null; } }//base64encode public static String base64decode(String text) { try { return new String(dec.decodeBuffer(text), DEFAULT_ENCODING); } catch (IOException e) { return null; } }//base64decode public static void main(String[] args) { String txt = "some text to be encrypted"; String key = "key phrase used for XOR-ing"; System.out.println(txt + " XOR-ed to: " + (txt = xorMessage(txt, key))); String encoded = base64encode(txt); System.out.println(" is encoded to: " + encoded + " and that is decoding to: " + (txt = base64decode(encoded))); System.out.print("XOR-ing back to original: " + xorMessage(txt, key)); } public static String xorMessage(String message, String key) { try { if (message == null || key == null) return null; char[] keys = key.toCharArray(); char[] mesg = message.toCharArray(); int ml = mesg.length; int kl = keys.length; char[] newmsg = new char[ml]; for (int i = 0; i < ml; i++) { newmsg[i] = (char)(mesg[i] ^ keys[i % kl]); }//for i return new String(newmsg); } catch (Exception e) { return null; } }//xorMessage }//class 

grazie ho reso questa class usando il tuo codice, forse qualcuno lo trova utile

crypter di oggetti

 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class ObjectCrypter { private Cipher deCipher; private Cipher enCipher; private SecretKeySpec key; private IvParameterSpec ivSpec; public ObjectCrypter(byte[] keyBytes, byte[] ivBytes) { // wrap key data in Key/IV specs to pass to cipher ivSpec = new IvParameterSpec(ivBytes); // create the cipher with the algorithm you choose // see javadoc for Cipher class for more info, eg try { DESKeySpec dkey = new DESKeySpec(keyBytes); key = new SecretKeySpec(dkey.getKey(), "DES"); deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public byte[] encrypt(Object obj) throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, IllegalBlockSizeException, ShortBufferException, BadPaddingException { byte[] input = convertToByteArray(obj); enCipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); return enCipher.doFinal(input); // cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // byte[] encypted = new byte[cipher.getOutputSize(input.length)]; // int enc_len = cipher.update(input, 0, input.length, encypted, 0); // enc_len += cipher.doFinal(encypted, enc_len); // return encypted; } public Object decrypt( byte[] encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException, ClassNotFoundException { deCipher.init(Cipher.DECRYPT_MODE, key, ivSpec); return convertFromByteArray(deCipher.doFinal(encrypted)); } private Object convertFromByteArray(byte[] byteObject) throws IOException, ClassNotFoundException { ByteArrayInputStream bais; ObjectInputStream in; bais = new ByteArrayInputStream(byteObject); in = new ObjectInputStream(bais); Object o = in.readObject(); in.close(); return o; } private byte[] convertToByteArray(Object complexObject) throws IOException { ByteArrayOutputStream baos; ObjectOutputStream out; baos = new ByteArrayOutputStream(); out = new ObjectOutputStream(baos); out.writeObject(complexObject); out.close(); return baos.toByteArray(); } } 

Cosa ne pensi di questo:

 private static byte[] xor(final byte[] input, final byte[] secret) { final byte[] output = new byte[input.length]; if (secret.length == 0) { throw new IllegalArgumentException("empty security key"); } int spos = 0; for (int pos = 0; pos < input.length; ++pos) { output[pos] = (byte) (input[pos] ^ secret[spos]); ++spos; if (spos >= secret.length) { spos = 0; } } return output; } 

Funziona bene per me ed è piuttosto compatto.

Ecco la mia implementazione da meta64.com come Spring Singleton. Se si desidera creare un’istanza di crittografia per ogni chiamata che potrebbe funzionare anche, e quindi è ansible rimuovere le chiamate ‘sincronizzate’, ma attenzione ‘cipher’ non è thread-safe.

 import java.security.Key; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("singleton") public class Encryptor { @Value("${aeskey}") private String keyStr; private Key aesKey = null; private Cipher cipher = null; synchronized private void init() throws Exception { if (keyStr == null || keyStr.length() != 16) { throw new Exception("bad aes key configured"); } if (aesKey == null) { aesKey = new SecretKeySpec(keyStr.getBytes(), "AES"); cipher = Cipher.getInstance("AES"); } } synchronized public String encrypt(String text) throws Exception { init(); cipher.init(Cipher.ENCRYPT_MODE, aesKey); return toHexString(cipher.doFinal(text.getBytes())); } synchronized public String decrypt(String text) throws Exception { init(); cipher.init(Cipher.DECRYPT_MODE, aesKey); return new String(cipher.doFinal(toByteArray(text))); } public static String toHexString(byte[] array) { return DatatypeConverter.printHexBinary(array); } public static byte[] toByteArray(String s) { return DatatypeConverter.parseHexBinary(s); } /* * DO NOT DELETE * * Use this commented code if you don't like using DatatypeConverter dependency */ // public static String toHexStringOld(byte[] bytes) { // StringBuilder sb = new StringBuilder(); // for (byte b : bytes) { // sb.append(String.format("%02X", b)); // } // return sb.toString(); // } // // public static byte[] toByteArrayOld(String s) { // int len = s.length(); // byte[] data = new byte[len / 2]; // for (int i = 0; i < len; i += 2) { // data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + // 1), 16)); // } // return data; // } } 

Prenderò in considerazione l’utilizzo di qualcosa come https://www.bouncycastle.org/ È una libreria precostruita che ti permette di crittografare qualsiasi cosa tu voglia con un numero di Cipher diversi. Capisco che vuoi solo proteggere dallo spionaggio, ma se davvero vuoi proteggere le informazioni, usando Base64 non ti proteggerò.

Ecco alcuni link che puoi leggere cosa supporta Java

Crittografia / decrittografia di un stream di dati.

Questo esempio dimostra come crittografare (utilizzando un algoritmo di crittografia simmetrica come AES, Blowfish, RC2, 3DES, ecc.) Una grande quantità di dati. I dati vengono passati in blocchi a uno dei metodi di crittografia: EncryptBytes, EncryptString, EncryptBytesENC o EncryptStringENC. (Il nome del metodo indica il tipo di input (stringa o array di byte) e il tipo di ritorno (stringa codificata o array di byte). Le proprietà FirstChunk e LastChunk vengono utilizzate per indicare se un blocco è il primo, il mezzo o l’ultimo di un stream per essere crittografato. Per impostazione predefinita, sia FirstChunk che LastChunk sono uguali a true, ovvero i dati trasmessi sono l’intero importo.

JCERefGuide

Esempi di crittografia Java

Puoi usare Jasypt

Con Jasypt, crittografare e controllare una password può essere semplice …

 StrongTextEncryptor textEncryptor = new StrongTextEncryptor(); textEncryptor.setPassword(myEncryptionPassword); 

crittografia:

 String myEncryptedText = textEncryptor.encrypt(myText); 

decrittazione:

 String plainText = textEncryptor.decrypt(myEncryptedText); 

Gradle:

 compile group: 'org.jasypt', name: 'jasypt', version: '1.9.2' 

Caratteristiche:

Jasypt ti offre tecniche di crittografia unidirezionale (digest) e bidirezionale.

API aperta da utilizzare con qualsiasi provider JCE e non solo con quello Java VM predefinito. Jasypt può essere facilmente utilizzato con fornitori noti come Bouncy Castle. Per saperne di più.

Maggiore sicurezza per le password dei tuoi utenti. Per saperne di più.

Supporto per la crittografia binaria. Jasypt consente il digest e la crittografia dei binari (array di byte). Cripta i tuoi oggetti o file quando necessario (per essere inviato in rete, per esempio).

Supporto per la crittografia dei numeri. Oltre a testi e binari, consente il digest e la crittografia dei valori numerici (BigInteger e BigDecimal, altri tipi numerici sono supportati durante la crittografia per la persistenza di Hibernate). Per saperne di più.

Completamente sicuro per i thread.

Supporto per il pooling di crittografia / digestione, al fine di ottenere alte prestazioni in sistemi multi-processore / multi-core.

Include una versione leggera (“lite”) della libreria per una migliore gestibilità in ambienti restrittivi delle dimensioni come le piattaforms mobili.

Fornisce strumenti di crittografia facili e senza configurazione per utenti nuovi alla crittografia e anche strumenti di crittografia standard altamente configurabili per utenti esperti.

Integrazione opzionale di Hibernate 3 e 4 per i campi persistenti delle quadro mappate in modo crittografato. La crittografia dei campi è definita nei file di mapping di Hibernate e rimane trasparente per il resto dell’applicazione (utile per dati personali sensibili, database con molti utenti abilitati alla lettura …). Cripta testi, binari, numeri, booleani, date … Ulteriori informazioni.

Perfettamente integrabile in un’applicazione Spring, con funzionalità di integrazione specifiche per Spring 2, Spring 3.0 e Spring 3.1. Tutti i digestori e i crittografi in jasypt sono progettati per essere facilmente utilizzati (istanziati, con l’aggiunta di dipendenze …) da Spring. E, a causa del loro essere thread-safe, possono essere utilizzati senza preoccupazioni di sincronizzazione in un ambiente orientato al singleton come Spring. Ulteriori informazioni: Spring 2, Spring 3.0, Spring 3.1.

Integrazione opzionale Spring Security (precedentemente Acegi Security) per l’esecuzione della crittografia delle password e l’abbinamento delle attività per il framework di sicurezza, migliorando la sicurezza delle password degli utenti utilizzando meccanismi di crittografia delle password più sicuri e fornendo un livello più elevato di configurazione e controllo. Per saperne di più.

Fornisce funzionalità avanzate per la crittografia di tutti o parte dei file di configurazione di un’applicazione, incluse informazioni sensibili come le password del database. Integrazione perfetta della configurazione crittografata in semplici applicazioni basate su Spring e / o Hibernate. Per saperne di più.

Fornisce strumenti CLI (Command Line Interface) di facile utilizzo per consentire agli sviluppatori di inizializzare i propri dati crittografati e includere operazioni di crittografia / decrittografia / digest in attività di manutenzione o script. Per saperne di più.

Si integra in Apache Wicket, per una crittografia più robusta degli URL nelle tue applicazioni sicure.

Guide complete e documentazione javadoc, per consentire agli sviluppatori di capire meglio cosa stanno realmente facendo ai propri dati.

Robusto supporto per charset, progettato per crittografare e digerire adeguatamente i testi indipendentemente dal set di caratteri originale. Supporto completo per lingue come giapponese, coreano, arabo … senza problemi di codifica o piattaforma.

Capacità di configurazione molto elevata: lo sviluppatore può implementare trucchi come istruire un “crittografico” per chiedere ad esempio un server HTTPS remoto per la password da utilizzare per la crittografia. Ti consente di soddisfare le tue esigenze di sicurezza.

Ecco una soluzione semplice con solo le dipendenze java.* E javax.crypto.* Per la crittografia dei byte che forniscono riservatezza e integrità . Deve essere indistinguibile con un attacco di testo in chiaro scelto .

Utilizza AES in modalità GCM senza riempimento, una chiave a 128 bit è derivata da PBKDF2 con molte iterazioni e un valore statico della password fornita. Questo fa sì che le password di forzatura brute siano difficili e distribuisce l’entropia sull’intera chiave.

Un vettore di inizializzazione casuale (IV) viene generato e verrà anteposto al testo cifrato. Inoltre, il byte statico 0x01 viene anteposto come il primo byte come ‘versione’.

L’intero messaggio va inserito nel codice di autenticazione dei messaggi (MAC) generato da AES/GCM .

Ecco qui, zero class di crittografia delle dipendenze esterne che fornisce riservatezza e integrità :

 package cryptor; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; /** * This class implements AES-GCM symmetric key encryption with a PBKDF2 derived password. * It provides confidentiality and integrity of the plaintext. * * @created 2018-02-25 */ public class AesGcmCryptor { // https://crypto.stackexchange.com/questions/26783/ciphertext-and-tag-size-and-iv-transmission-with-aes-in-gcm-mode private static final byte VERSION_BYTE = 0x01; private static final int VERSION_BYTE_LENGTH = 1; private static final int AES_KEY_BITS_LENGTH = 128; private static final int GCM_IV_BYTES_LENGTH = 12; private static final int GCM_TAG_BYTES_LENGTH = 16; private static final int PBKDF2_ITERATIONS = 16384; private static final byte[] PBKDF2_SALT = hexStringToByteArray("4d3fe0d71d2abd2828e7a3196ea450d4"); /** * Decrypts an AES-GCM encrypted ciphertext and is * the reverse operation of {@link AesGcmCryptor#encrypt(char[], byte[])} * * @param password passphrase for decryption * @param ciphertext encrypted bytes * * @return plaintext bytes * * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws InvalidKeySpecException * @throws InvalidAlgorithmParameterException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws IllegalArgumentException if the length or format of the ciphertext is bad */ public byte[] decrypt(char[] password, byte[] ciphertext) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, BadVersionException { // input validation if (ciphertext == null) { throw new IllegalArgumentException("Ciphertext cannot be null."); } if (ciphertext.length <= VERSION_BYTE_LENGTH + GCM_IV_BYTES_LENGTH + GCM_TAG_BYTES_LENGTH) { throw new IllegalArgumentException("Ciphertext too short."); } // the version must match, we don't decrypt other versions if (ciphertext[0] != VERSION_BYTE) { throw new BadVersionException(); } // input seems legit, lets decrypt and check integrity // derive key from password SecretKey key = deriveAesKey(password, PBKDF2_SALT, AES_KEY_BITS_LENGTH); // init cipher Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); GCMParameterSpec params = new GCMParameterSpec(GCM_TAG_BYTES_LENGTH * 8, ciphertext, VERSION_BYTE_LENGTH, GCM_IV_BYTES_LENGTH ); cipher.init(Cipher.DECRYPT_MODE, key, params); final int ciphertextOffset = VERSION_BYTE_LENGTH + GCM_IV_BYTES_LENGTH; // add version and IV to MAC cipher.updateAAD(ciphertext, 0, ciphertextOffset); // decipher and check MAC return cipher.doFinal(ciphertext, ciphertextOffset, ciphertext.length - ciphertextOffset); } /** * Encrypts a plaintext with a password. * * The encryption provides the following security properties: * Confidentiality + Integrity * * This is achieved my using the AES-GCM AEAD blockmode with a randomized IV. * * The tag is calculated over the version byte, the IV as well as the ciphertext. * * Finally the encrypted bytes have the following structure: * 
 * +-------------------------------------------------------------------+ * | | | | | * | version | IV bytes | ciphertext bytes | tag | * | | | | | * +-------------------------------------------------------------------+ * Length: 1B 12B len(plaintext) bytes 16B * 

* Note: There is no padding required for AES-GCM, but this also implies that * the exact plaintext length is revealed. * * @param password password to use for encryption * @param plaintext plaintext to encrypt * * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws NoSuchPaddingException * @throws InvalidAlgorithmParameterException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeySpecException */ public byte[] encrypt(char[] password, byte[] plaintext) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException { // initialise random and generate IV (initialisation vector) SecretKey key = deriveAesKey(password, PBKDF2_SALT, AES_KEY_BITS_LENGTH); final byte[] iv = new byte[GCM_IV_BYTES_LENGTH]; SecureRandom random = SecureRandom.getInstanceStrong(); random.nextBytes(iv); // encrypt Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_BYTES_LENGTH * 8, iv); cipher.init(Cipher.ENCRYPT_MODE, key, spec); // add IV to MAC final byte[] versionBytes = new byte[] { VERSION_BYTE }; cipher.updateAAD(versionBytes); cipher.updateAAD(iv); // encrypt and MAC plaintext byte[] ciphertext = cipher.doFinal(plaintext); // prepend VERSION and IV to ciphertext byte[] encrypted = new byte[1 + GCM_IV_BYTES_LENGTH + ciphertext.length]; int pos = 0; System.arraycopy(versionBytes, 0, encrypted, 0, VERSION_BYTE_LENGTH); pos += VERSION_BYTE_LENGTH; System.arraycopy(iv, 0, encrypted, pos, iv.length); pos += iv.length; System.arraycopy(ciphertext, 0, encrypted, pos, ciphertext.length); return encrypted; } /** * We derive a fixed length AES key with uniform entropy from a provided * passphrase. This is done with PBKDF2/HMAC256 with a fixed count * of iterations and a provided salt. * * @param password passphrase to derive key from * @param salt salt for PBKDF2 if possible use a per-key salt, alternatively * a random constant salt is better than no salt. * @param keyLen number of key bits to output * * @return a SecretKey for AES derived from a passphrase * * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ private SecretKey deriveAesKey(char[] password, byte[] salt, int keyLen) throws NoSuchAlgorithmException, InvalidKeySpecException { if (password == null || salt == null || keyLen <= 0) { throw new IllegalArgumentException(); } SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(password, salt, PBKDF2_ITERATIONS, keyLen); SecretKey pbeKey = factory.generateSecret(spec); return new SecretKeySpec(pbeKey.getEncoded(), "AES"); } /** * Helper to convert hex strings to bytes. * * May be used to read bytes from constants. */ private static byte[] hexStringToByteArray(String s) { if (s == null) { throw new IllegalArgumentException("Provided `null` string."); } int len = s.length(); if (len % 2 != 0) { throw new IllegalArgumentException("Invalid length: " + len); } byte[] data = new byte[len / 2]; for (int i = 0; i < len - 1; i += 2) { byte b = (byte) toHexDigit(s, i); b <<= 4; b |= toHexDigit(s, i + 1); data[i / 2] = b; } return data; } private static int toHexDigit(String s, int pos) { int d = Character.digit(s.charAt(pos), 16); if (d < 0) { throw new IllegalArgumentException("Cannot parse hex digit: " + s + " at " + pos); } return d; } }

Here the entire project with a nice CLI: https://github.com/trichner/tcrypt

This is method i used.this is simple but it has better protection. https://github.com/chamikaras/simpleEncryptor

Read readme on this project.This is simple to used.

 public SimpleEncryptor(int MaximumLength) { //initialize encryption Key pattern variable pattern = new Integer[MaximumLength]; //Generate pattern pattern =GenarateEncryptionPattern(MaximumLength); } private Integer[] GenarateEncryptionPattern(int Length) { Integer[] randomPattern = new Integer[Length]; //generate encryption pattern for (int i = 0; i < Length; i++) { //make random encrypt key Random random = new Random(); randomPattern[i] = random.nextInt(9); } return randomPattern; } public void simpleEncryptData(String data) { for (int i=0; i 

}

I Have made this Simple Solution for You.

Main Point is Encrypt String by shifting ASCII Value of the Integer by the secret key you Provide.

Here is the Solution:

 public String encryptText(String toEncrypt) { String tempEn = toEncrypt + ""; String encryptText =""; for(int i=0;i 

Steps to Encode:

  1. Scan each character of String, Read ASCII of that character and add it with secret key as 148113 in this case.
  2. Convert shifted Integer into Character and concatenate to the String encryptText and finally return it.

Steps to Decode:

  1. Scan each character of String, Read ASCII of that character and subtract it with secret key as previous.
  2. Convert that value to character and concatenate with decodeText .

As previous encode output is always String '???' and vary according to number of character of input String .

 String s1="arshad"; char[] s2=s1.toCharArray(); int s3= s2.length; System.out.println(s3); int i=0; // for(int j=0;j 
 public static String encryptParams(String myTextInput) { String myKey = "40674244454045cb9a70040a30e1c007"; String myVector = "@1B2c3D4e5F6g7H8"; String encData = ""; try{ JavaEncryprtionUtil encUtil = new JavaEncryprtionUtil(); encData = Base64.encodeToString(encUtil.encrypt(myTextInput.getBytes("UTF-8"), myKey.getBytes("UTF-8"), myVector.getBytes("UTF-8")),Base64.DEFAULT); System.out.println(encData); }catch(NoSuchAlgorithmException ex){ ex.printStackTrace(); }catch(NoSuchPaddingException ex){ ex.printStackTrace(); }catch(InvalidKeyException ex){ ex.printStackTrace(); }catch(InvalidAlgorithmParameterException ex){ ex.printStackTrace(); }catch(IllegalBlockSizeException ex){ ex.printStackTrace(); }catch(BadPaddingException ex){ ex.printStackTrace(); }catch(UnsupportedEncodingException ex){ ex.printStackTrace(); } return encData; } 

You might want to consider some automated tool to do the encryption / decryption code generation eg. https://www.stringencrypt.com/java-encryption/

It can generate different encryption and decryption code each time for the string or file encryption.

It’s pretty handy when it comes to fast string encryption without using RSA, AES etc.

Sample results:

 // encrypted with https://www.stringencrypt.com (v1.1.0) [Java] // szTest = "Encryption in Java!" String szTest = "\u9E3F\uA60F\uAE07\uB61B\uBE1F\uC62B\uCE2D\uD611" + "\uDE03\uE5FF\uEEED\uF699\uFE3D\u071C\u0ED2\u1692" + "\u1E06\u26AE\u2EDC"; for (int iatwS = 0, qUJQG = 0; iatwS < 19; iatwS++) { qUJQG = szTest.charAt(iatwS); qUJQG ++; qUJQG = ((qUJQG << 5) | ( (qUJQG & 0xFFFF) >> 11)) & 0xFFFF; qUJQG -= iatwS; qUJQG = (((qUJQG & 0xFFFF) >> 6) | (qUJQG << 10)) & 0xFFFF; qUJQG ^= iatwS; qUJQG -= iatwS; qUJQG = (((qUJQG & 0xFFFF) >> 3) | (qUJQG << 13)) & 0xFFFF; qUJQG ^= 0xFFFF; qUJQG ^= 0xB6EC; qUJQG = ((qUJQG << 8) | ( (qUJQG & 0xFFFF) >> 8)) & 0xFFFF; qUJQG --; qUJQG = (((qUJQG & 0xFFFF) >> 5) | (qUJQG << 11)) & 0xFFFF; qUJQG ++; qUJQG ^= 0xFFFF; qUJQG += iatwS; szTest = szTest.substring(0, iatwS) + (char)(qUJQG & 0xFFFF) + szTest.substring(iatwS + 1); } System.out.println(szTest); 

We use it all the time in our company.