如何在Java中encryptionstring

我需要的是encryption将出现在二维条码(PDF-417)中的string,所以当有人得到一个想法来扫描它将无法读取。

其他需求:

  • 不应该是复杂的
  • 它不应该由RSA,PKI基础设施,密钥对等组成。

它必须足够简单,以摆脱周围的人窥探,并容易解密为有兴趣获得该数据的其他公司。 他们给我们打电话,告诉他们标准或给他们一些简单的密钥,然后可以用来解密。

可能这些公司可能会使用不同的技术,所以坚持一些与特定平台或技术无关的标准是很好的。

你有什么build议? 有没有一些Java类encryption()解密()没有太多复杂的实现高安全标准?

我build议使用一些标准的对称密码,如DES , 3DES或AES等 。 虽然这不是最安全的algorithm,但是有很多的实现,你只需要把密钥交给任何人来解密条形码中的信息。 javax.crypto.Cipher就是你想要在这里工作的。

假设要encryption的字节在

byte[] input; 

接下来,您将需要密钥和初始化向量字节

 byte[] keyBytes; byte[] ivBytes; 

现在您可以初始化您select的algorithm的密码:

 // 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"); 

encryption将如下所示:

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

解密如下:

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

警告

不要将其用作某种安全度量。

本文中的encryption机制是一次性密码,这意味着攻击者可以使用两条encryption的消息轻松地恢复密钥。 异或2encryption的消息,你得到的密钥。 那简单!

穆萨指出


我在Sun的JRE中使用了Sun的Base64Encoder / Decoder,以避免lib中另一个JAR。 从使用OpenJDK或其他JRE的angular度来看,这是很危险的。 除此之外,还有另外一个原因,我应该考虑使用编码器/解码器的Apache公共库?

 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 

这是通过谷歌显示的第一页,所有的实施安全漏洞让我畏惧,所以我张贴这个来添加有关encryption的信息,因为它已经7年从原信息。 我拥有计算机工程硕士学位 ,花了很多时间学习和学习密码学,所以我投入了2美分让互联网变得更安全。

另外,请注意,对于特定的情况,大量的实现可能是安全的,但为什么使用这些实现可能会意外地犯了一个错误? 除非你有特定的理由,否则使用你可用的最强大的工具。 总的来说,我强烈build议使用图书馆,如果可以的话,远离细节的细节。 我推荐Jasypt 。

下面我将概述安全对称密码学的基础知识,并指出我在网上看到的常见错误。

首先你需要select一个对称密钥块密码。 分组密码是一种用来创build伪随机性的工具。 请务必永远不要使用DES ,我甚至说永远不要使用3DES 。 即使是斯诺登的NSA版本也能够validation的唯一分组密码是真正尽可能接近伪随机的,即AES 256 。

现在我们来谈谈encryption模式。 从不使用ECB,这是隐藏重复的数据,如着名的Linux企鹅所示 。

在Java中实现时请注意,如果使用下面的代码,ECB模式默认设置为:

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

…避免这个! 在网上有很多例子

如果你不知道你在做什么,我会严格遵守GCM,如前所述,如果你真的不知道只是使用Jasypt 。 我甚至会提到的其他模式还有CBC和CTR模式,但是与GCM不同,攻击者可以在这些模式下修改encryption的消息,这就是为什么它们不是完全安全的原因。

所以在典型的java实现中,这是你想要的设置:

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

GCMbuild立在CTR模式之上,不需要填充。 但是,如果出于任何原因,您select使用例如CBC模式这样做与PKCS7Padding如下:

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

另一个非常重要的说明是,在密码学中,密钥和密码不是一回事。 密码学中的一个关键要求有一定的熵和随机性被认为是安全的。 这就是为什么你需要确保使用密码库密钥生成algorithm来select密钥。

随着一个关键,我们也有一个叫做IV的东西。 虽然密钥是一个秘密,你应该只与你想要解密的人分享,IV是公开的。 它用于确保如果您encryption两个相同的消息,encryption看起来不同。 现在大多数人都不知道的是,IV不能重复相同的密钥。 当你在GCM,CBC,CTR等模式中重复使用IV时,实际上会危及整个系统的安全。 这就是为什么你需要确保你的IV不是静态的,并且你正在使用正确的密码库来生成一个随机的IV,而且意外地创build了两个相同的概率。

我现在希望通过其他所有的职位,并编辑他们以消除漏洞。 但是为了让你的生活变得轻松,这里是你如何使用它!

摇篮

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

build立

 myPassword = "A Strong Password" BasicTextEncryptor textEncryptor = new BasicTextEncryptor(); textEncryptor.setPassword(myPassword); 

encryption

 String myEncryptedText = textEncryptor.encrypt(myText); 

解密

 String plainText = textEncryptor.decrypt(myEncryptedText); 

为了更安全地使用下面提供的StrongTextEncryptor util类,但速度较慢。 (您可能需要下载并安装Javaencryption扩展(JCE)无限强度pipe辖权策略文件才能使用它):

build立

 myPassword = "A Strong Password" StrongTextEncryptor textEncryptor = new StrongTextEncryptor(); textEncryptor.setPassword(myPassword); 

encryption

 String myEncryptedText = textEncryptor.encrypt(myText); 

解密

 String plainText = textEncryptor.decrypt(myEncryptedText); 

这不是很清洁吗? 🙂

请注意,当使用Jasypt时,您不必担心上面讨论的密钥是真正的随机密码,只需使用强密码,它们的库将您的强密码转换为适当的encryption密钥。 但记住一个弱密码仍然是一个弱密码

Android开发者

这里需要指出的一点很重要,那就是知道你的android代码是可逆的。 这意味着如果您在密码中以纯文本forms存储密码。 黑客可以轻松找回它。 通常对于这种types的encryption你想使用非对称密码等等。 这超出了这篇文章的范围,所以我将避免潜入其中。

2013年的一个有趣的阅​​读 :指出在android中88%的Crypto实现是不正确的,这真的是我来这里的基础,并咆哮这么多。

谢谢你让这个类使用你的代码,也许有人认为它是userfull

对象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, 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(); } } 

这个怎么样:

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

为我工作很好,是相当紧凑的。

这是我从meta64.com作为Spring Singleton的实现。 如果你想为每个呼叫创build一个Ciper实例,那么你也可以删除'synchronized'调用,但是要注意'cipher'不是线程安全的。

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

这里有一些链接,你可以阅读什么Java支持

encryption/解密数据stream。

本示例演示如何对大量数据进行encryption(使用对称encryptionalgorithm,如AES,Blowfish,RC2,3DES等)。 数据以块的forms传递给其中一种encryption方法:EncryptBytes,EncryptString,EncryptBytesENC或EncryptStringENC。 (方法名称指示input的types(string或字节数组)和返回types(编码的string或字节数组)FirstChunk和LastChunk属性用于指示一个块是stream中的第一个,中间还是最后一个默认情况下,FirstChunk和LastChunk都是true,表示传递的数据是全部数据。

JCERefGuide

Javaencryption示例

你可以使用Jasypt

使用Jasypt,encryption和检查密码可以像…

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

encryption:

 String myEncryptedText = textEncryptor.encrypt(myText); 

解密:

 String plainText = textEncryptor.decrypt(myEncryptedText); 

摇篮:

编译组:'org.jasypt',名称:'jasypt',版本:'1.9.2'

特征

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

你可能想要考虑一些自动化工具来执行encryption/解密代码生成,例如。 https://www.stringencrypt.com/java-encryption/

它可以为每个string或文件encryption生成不同的encryption和解密代码。

当涉及到不使用RSA,AES等快速stringencryption时,它非常方便。

样品结果:

 // 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); 

我们一直在我们公司使用它。

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