[英]C's Crypt() like function in Java
我一直在阅读 Java 中有关加密密码的一些代码。 这似乎有点计算密集型。
有没有一种快速的方法来加密类似于 C 或 Ruby 的字符串?
例如,在 Ruby 中:
'hello'.crypt('$6$salt') # => "$6$salt$ghQ6Rhatj/sug12c6v8Ao/bXUoyJ1O1SqdumufgGEO3b3NYPvm/dSWDKWfNm1VxFoFiy/cw9eRaY0xu4GDQSU/"
方法String#crypt()
来自 C,在 Linux 中用于将散列密码存储在/etc/shadow
中:
$ sudo cat /etc/shadow | grep $USER
sourav:$6$Vx0wkV1M2PM43WOE$b2pYu.funKjk/snGSqiMTgh1e9dGQYDEKrjfuc2T/tP5qs7lXU56MjFvWd35rgzmYBXK33DrjQqnxTcPtcMXi/:18013:0:99999:7:::
这是一个小程序...
知道我的系统密码是55,在Ruby中:
pass = IO.readlines('/etc/shadow').find { |x| x.start_with?(ENV['USER']) }
=> "sourav:$6$Vx0wkV1M2PM43WOE$b2pYu.funKjk/snGSqiMTgh1e9dGQYDEKrjfuc2T/tP5qs7lXU56MjFvWd35rgzmYBXK33DrjQqnxTcPtcMXi/:18013:0:99999:7:::\n"
h = ?$ + pass.split(?$)[1..2].join(?$)
=> "$6$Vx0wkV1M2PM43WOE"
s = pass.split(?$)[-1].split(?:)[0]
=> "b2pYu.funKjk/snGSqiMTgh1e9dGQYDEKrjfuc2T/tP5qs7lXU56MjFvWd35rgzmYBXK33DrjQqnxTcPtcMXi/"
hs = h + ?$ + s
=> "$6$Vx0wkV1M2PM43WOE$b2pYu.funKjk/snGSqiMTgh1e9dGQYDEKrjfuc2T/tP5qs7lXU56MjFvWd35rgzmYBXK33DrjQqnxTcPtcMXi/"
'55'.crypt(h) == hs
=> true
所以系统可以确认我的密码是55,让我登录。
Java中是否有类似的方法可以加密字符串? 如果给出了帐户密码,我可以类似地运行 'string.crypt("$6$salt")' 并解密/etc/shadow
的帐户密码吗?
Java 自 1.4 起包含名为javax.crypto
的 package ,它允许您使用密码加密和解密数据。
TutorialsPoint有这个 package 的教程。 这是一个小的 Java 片段,它首先加密数据,然后解密它:
public class CipherSample {
public static void main(String args[]) throws Exception{
//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withRSA");
//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//Initializing the key pair generator
keyPairGen.initialize(2048);
//Generating the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();
//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, pair.getPublic());
//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();
cipher.update(input);
//encrypting the data
byte[] cipherText = cipher.doFinal();
System.out.println(new String(cipherText, "UTF8"));
//Initializing the same cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());
//Decrypting the text
byte[] decipheredText = cipher.doFinal(cipherText);
System.out.println(new String(decipheredText));
}
}
没有那么简单,但仍然很简单。
如果给出帐户密码,则解密 /etc/shadow 的帐户密码
crypt() function 没有加密,function 创建一个加盐密码 hash。
Hash 是一种单向 function,其主要功能之一是没有人应该能够根据(加密)hash 值恢复密码。
所以系统可以确认我的密码是55,让我登录。
这个有可能。 实际上,您计算了一个新的盐渍 hash(使用相同的盐)并与存储的值进行比较。
Java中是否有类似的方法可以加密字符串?
import org.apache.commons.codec.digest.Crypt;
...
String hash = Crypt.crypt("password".getBytes());
System.out.println("salted hash: "+hash);
// salt is $X$some_bytes
String salt = hash.substring(0, hash.indexOf("$", 3));
System.out.println("salt: "+salt);
// validation:
String testString = Crypt.crypt("password", salt);
if(testString.equals(hash)) {
System.out.println("Password match");
} else {
System.out.println("Invalid password");
}
crypt C 库 function 使用 DES 作为其加密。 如果您想要 Java 中的结果完全相同,则必须使用相同的算法。
简而言之:
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey desKey = keygenerator.generateKey();
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, desKey);
byte[] encrypted = desCipher.doFinal(clearText.getBytes());
您可以在这里找到教程: https://www.mkyong.com/java/jce-encryption-data-encryption-standard-des-tutorial/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.