Java 如何检查字符串是否加密?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21732018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if a string is encrypted or not?
提问by Rahul Gupta
I am using this encryption method to encrypt and decrypt a certain string :-
我正在使用这种加密方法来加密和解密某个字符串:-
package encryption;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AES {
private static final String ALGO = "AES";
private static final byte[] keyValue =
new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
}
It works fine.
它工作正常。
The issue is that how will i get to know that the string which is to be decrypted is encrypted ?
问题是我如何知道要解密的字符串是加密的?
I mean i could pass a long "not encrypted" string to the decrypt method and it still will work.
我的意思是我可以将一个长的“未加密”字符串传递给解密方法,它仍然可以工作。
Any suggestions.
有什么建议。
回答by chrylis -cautiouslyoptimistic-
There's no definitive way to tell; the only thing you can do is look at a string and see if it looks like something intelligible (roughly speaking, something for which file
would return something more specific than "data"). Unless you have some characteristic that you can use to identify "plain text" (maybe everything's ASCII, or all Unicode code points for $LANGUAGE), there's no inherent difference between ciphertext and arbitrary binary data.
没有确定的方法可以说明;你唯一能做的就是查看一个字符串,看看它是否看起来像一些可以理解的东西(粗略地说,它file
会返回比“数据”更具体的东西)。除非您有一些特征可以用来识别“纯文本”(可能一切都是 ASCII,或者 $LANGUAGE 的所有 Unicode 代码点),否则密文和任意二进制数据之间没有内在的区别。
回答by placeybordeaux
There are no perfect answers to this question, as there is no 100% sure way to know if something is encrypted. However it should be randomly distributed across all possible base64 strings which means it should look a lot different than plaintext. One way you can tell the difference between english and base64 encrypted strings is to see how many spaces there are.
这个问题没有完美的答案,因为没有 100% 确定的方法来知道某些东西是否被加密。然而,它应该随机分布在所有可能的 base64 字符串中,这意味着它看起来应该与纯文本有很大不同。区分 english 和 base64 加密字符串的一种方法是查看有多少空格。
There are 92 spaces in this post, but the character space does not appear in base64. If you are dealing with stuff other than plaintext English it will get more interesting.
这篇文章有92个空格,但是base64中没有出现字符空格。如果你正在处理明文英语以外的东西,它会变得更有趣。
回答by Michael J. Gray
You can determine if something is encrypted with a particular key, algorithm, mode, and padding scheme by simply trying to decrypt it.
您可以通过简单地尝试解密来确定某些内容是否使用特定的密钥、算法、模式和填充方案加密。
If you're decrypting the data, you know the padding scheme being used, and you can verify if the padding is correct when you try to decrypt it. If you cannot reliably strip the padding from the original message, you know you have a problem!
如果您正在解密数据,您就知道所使用的填充方案,并且您可以在尝试解密时验证填充是否正确。如果您不能可靠地从原始消息中去除填充,您就知道有问题!
One of the benefits of the CBC mode, which is supported in almost every widely used cryptography library containing symmetric ciphers (like AES) is that each block depends on the previous one in terms of its data. This means that errors will propagate and you are more likely to fail to decrypt data that was not actually encrypted or has been corrupted accidentally in some fashion.
CBC 模式的好处之一是几乎所有包含对称密码(如 AES)的广泛使用的密码库都支持该模式,因为每个块的数据都依赖于前一个块。这意味着错误会传播,并且您更有可能无法解密实际上未加密或以某种方式意外损坏的数据。
I believe that this is probably the best bang for your lines of code to test if the data passed in was encrypted with the specific key, algorithm, mode, and padding scheme.
我相信这可能是您的代码行测试传入的数据是否使用特定密钥、算法、模式和填充方案加密的最佳方法。
EDIT
编辑
But, if you need to verify with high certainty that the key is correct, you need to add a message authentication code (MAC) at the end of your ciphertext or plaintext.
但是,如果您需要高度确定地验证密钥是否正确,则需要在密文或明文的末尾添加消息验证码 (MAC)。
You can form your message like this:
你可以像这样形成你的消息:
CIPHERTEXT = ENCRYPT(KEY_1, PADDING, MODE, PLAINTEXT)
MESSAGE = CIPHERTEXT || HMAC(KEY_2, CIPHERTEXT)
CIPHERTEXT
is defined as the result of encryption of plaintext under a specific key, padding, and mode of operation
CIPHERTEXT
定义为在特定密钥、填充和操作模式下对明文进行加密的结果
MESSAGE
is defined as the result of CIPHERTEXT
having the HMAC
result binary-concatenated (||
) to it.
MESSAGE
被定义为将结果二进制连接 ( )CIPHERTEXT
的HMAC
结果||
。
KEY_1
is a cryptographically secure key independent of KEY_2
, another cryptographically secure key.
KEY_1
是一个独立于KEY_2
另一个密码安全密钥的密码安全密钥。
The reason you want to compute the HMAC
against the CIPHERTEXT
is because you don't want to have to actually perform decryption to verify if the message is legitimate.
之所以要计算的HMAC
反对CIPHERTEXT
是因为你不希望有实际执行解密,验证消息是否合法。
You will have to start an encrypted session and then exchange KEY_2
over that encrypted channel, meaning you have added key management overhead and code complexity, but you have a 1/1^256 (at the very least) probability of seeing an incorrect message pass through the HMAC
check.
您将必须启动加密会话,然后KEY_2
通过该加密通道进行交换,这意味着您增加了密钥管理开销和代码复杂性,但您有 1/1^256(至少)看到错误消息通过的可能性该HMAC
检查。
Once you verify the result of HMAC
you can be certain the message is probably actually encrypted under KEY_1
, assuming no leaks have happened since the start of the session or the lifetime of the message.
一旦您验证了结果,HMAC
您就可以确定该消息可能实际上是在 下加密的KEY_1
,假设自会话开始或消息的生命周期以来没有发生任何泄漏。
回答by barak manos
You seem to be using a symmetric encryption/decryption scheme, where both sides can encrypt and decrypt messages using the same key, which is known onlyto them.
您似乎正在使用对称加密/解密方案,其中双方可以使用相同的密钥加密和解密消息,只有他们知道。
Both sides can agree on a correctness-verification method, for example, CRC.
双方可以就正确性验证方法达成一致,例如CRC。
Unlike with the key, which must remain a secret, this method can be publicly announced.
与必须保密的密钥不同,这种方法可以公开宣布。
Only owners of the secret key will be able to generate an authentic encrypted string, which can be verified using this method after decryption.
只有密钥的所有者才能生成真实的加密字符串,解密后可以使用此方法对其进行验证。
Any other string sent to decryption will simply fail the CRC test.
发送到解密的任何其他字符串都将无法通过 CRC 测试。
BTW, the authentication method is usually a hashing algorithm such as SHA, HMAC, etc. due to its nature, CRC would generally be more vulnerable to chosen-ciphertext attacks, where a malicious party generates random strings hoping that some of them will be detected as genuine.
顺便说一句,身份验证方法通常是散列算法,例如 SHA、HMAC 等。由于其性质,CRC 通常更容易受到选择密文攻击,其中恶意方生成随机字符串希望其中一些会被检测到作为正品。
回答by Danubian Sailor
Certainly possible, assuming the string is long enough. Those guys are detecting encrypted keys in memory dumps. Of course, there's no 100% guarantee - simple contrexample, you can encode encoded string, therefore your input looks already like a key.
当然可能,假设字符串足够长。那些家伙正在检测内存转储中的加密密钥。当然,没有 100% 保证 - 简单的例子,您可以对编码的字符串进行编码,因此您的输入看起来已经像一个键。
Generally, encrypted, encoded or hashed byte sequences looks like random sequences.They have higher entropy, the distribution of bits is more homogenous, you can't compress them etc.
通常,加密、编码或散列的字节序列看起来像随机序列。它们具有更高的熵,位的分布更均匀,您无法压缩它们等。
Best try is to analyse how randomly the bits are distributed. For BASE64 you analyse only 6 bits etc.
最好的尝试是分析位分布的随机性。对于 BASE64,您只分析 6 位等。