How to encrypt String in Java

2018-12-31 15:26发布

What I need is to encrypt string which will show up in 2D barcode(PDF-417) so when someone get an idea to scan it will get nothing readable.

Other requirements:

  • should not be complicated
  • it should not consist of RSA, PKI infrastructure, key pairs, etc.

It must be simple enough to get rid of the people snooping around, and easy to decrypt for other companies interested in getting that data. They call us, we tell them the standard or give them some simple key which can then be used for decryption.

Probably those companies could use different technologies so it would be good to stick to some standard which is not tied to some special platform or technology.

What do you suggest? Is there some Java class doing encrypt() decrypt() without much complication in achieving high security standards?

15条回答
高级女魔头
2楼-- · 2018-12-31 15:59

Warning

Do not use this as some kind of security measurement.

The encryption mechanism in this post is a One-time pad, which means that the secret key can be easily recovered by an attacker using 2 encrypted messages. XOR 2 encrypted messages and you get the key. That simple!

Pointed out by Moussa


I am using Sun's Base64Encoder/Decoder which is to be found in Sun's JRE, to avoid yet another JAR in lib. That's dangerous from point of using OpenJDK or some other's JRE. Besides that, is there another reason I should consider using Apache commons lib with 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
查看更多
何处买醉
3楼-- · 2018-12-31 15:59

You can use Jasypt

With Jasypt, encrypting and checking a password can be as simple as...

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

Encryption:

String myEncryptedText = textEncryptor.encrypt(myText);

Decryption:

String plainText = textEncryptor.decrypt(myEncryptedText);

Gradle:

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

Features:

Jasypt provides you with easy unidirectional (digest) and bidirectional encryption techniques.

Open API for use with any JCE provider, and not only the default Java VM one. Jasypt can be easily used with well-known providers like Bouncy Castle. Learn more.

Higher security for your users' passwords. Learn more.

Binary encryption support. Jasypt allows the digest and encryption of binaries (byte arrays). Encrypt your objects or files when needed (for being sent over the net, for example).

Number encryption support. Besides texts and binaries, it allows the digest and encryption of numeric values (BigInteger and BigDecimal, other numeric types are supported when encrypting for Hibernate persistence). Learn more.

Completely thread-safe.

Support for encryptor/digester pooling, in order to achieve high performance in multi-processor/multi-core systems.

Includes a lightweight ("lite") version of the library for better manageability in size-restrictive environments like mobile platforms.

Provides both easy, no-configuration encryption tools for users new to encryption, and also highly configurable standard encryption tools, for power-users.

Hibernate 3 and 4 optional integration for persisting fields of your mapped entities in an encrypted manner. Encryption of fields is defined in the Hibernate mapping files, and it remains transparent for the rest of the application (useful for sensitive personal data, databases with many read-enabled users...). Encrypt texts, binaries, numbers, booleans, dates... Learn more.

Seamlessly integrable into a Spring application, with specific integration features for Spring 2, Spring 3.0 and Spring 3.1. All the digesters and encryptors in jasypt are designed to be easily used (instantiated, dependency-injected...) from Spring. And, because of their being thread-safe, they can be used without synchronization worries in a singleton-oriented environment like Spring. Learn more: Spring 2, Spring 3.0, Spring 3.1.

Spring Security (formerly Acegi Security) optional integration for performing password encryption and matching tasks for the security framework, improving the security of your users' passwords by using safer password encryption mechanisms and providing you with a higher degree of configuration and control. Learn more.

Provides advanced functionality for encrypting all or part of an application's configuration files, including sensitive information like database passwords. Seamlessly integrate encrypted configuration into plain, Spring-based and/or Hibernate-enabled applications. Learn more.

Provides easy to use CLI (Command Line Interface) tools to allow developers initialise their encrypted data and include encryption/decryption/digest operations in maintenance tasks or scripts. Learn more.

Integrates into Apache Wicket, for more robust encryption of URLs in your secure applications.

Comprehensive guides and javadoc documentation, to allow developers to better understand what they are really doing to their data.

Robust charset support, designed to adequately encrypt and digest texts whichever the original charset is. Complete support for languages like Japanese, Korean, Arabic... with no encoding or platform issues.

Very high level of configuration capabilities: The developer can implement tricks like instructing an "encryptor" to ask a, for example, remote HTTPS server for the password to be used for encryption. It lets you meet your security needs.

查看更多
萌妹纸的霸气范
4楼-- · 2018-12-31 16:01

How about this:

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;
}

Works fine for me and is rather compact.

查看更多
浅入江南
5楼-- · 2018-12-31 16:04
String s1="arshad"; 
char[] s2=s1.toCharArray(); 
int s3= s2.length; 

  System.out.println(s3);
 int i=0; 

// for(int j=0;j<s3;j++) 
// System.out.println(s2[j]); 

for(i=0;i<((s3)/2);i++) { 

char z,f=10; 
z=(char) (s2[i] * f); 
s2[i]=s2[(s3-1)-i]; 
s2[(s3-1)-i]=z; 

String b=new String(s2);

 print(b);  }
查看更多
看淡一切
6楼-- · 2018-12-31 16:09

thanks ive made this class using your code maybe someone finds it userfull

object crypter

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, e.g.
    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();

}


}
查看更多
梦醉为红颜
7楼-- · 2018-12-31 16:09

Here are some links you can read what Java supports

Encrypting/decrypting a data stream.

This example demonstrates how to encrypt (using a symmetric encryption algorithm such as AES, Blowfish, RC2, 3DES, etc) a large amount of data. The data is passed in chunks to one of the encrypt methods: EncryptBytes, EncryptString, EncryptBytesENC, or EncryptStringENC. (The method name indicates the type of input (string or byte array) and the return type (encoded string or byte array). The FirstChunk and LastChunk properties are used to indicate whether a chunk is the first, middle, or last in a stream to be encrypted. By default, both FirstChunk and LastChunk equal true -- meaning that the data passed is the entire amount.

JCERefGuide

Java Encryption Examples

查看更多
登录 后发表回答