Cryptography 我的密码解密类有多安全?

Cryptography 我的密码解密类有多安全?,cryptography,encryption,password-protection,Cryptography,Encryption,Password Protection,我是任何解密的初学者。我写了一个我认为应该很安全的类。你能对我如何改进算法提出建设性的批评吗 package main; import java.util.Random; public class Main { public static void main(String[] args) { //we will be playing around with this string new Main("1234567890abc"); } priv

我是任何解密的初学者。我写了一个我认为应该很安全的类。你能对我如何改进算法提出建设性的批评吗

package main;

import java.util.Random;

public class Main {

   public static void main(String[] args) {
      //we will be playing around with this string
      new Main("1234567890abc");
   }

   private Random rnd;
   private byte[] randoms;

   /**
    * Starts up RNG
    * Prints out a test
    */
   public Main(String password) {
      //random long generated from the password
      long randomLong = randomNumber(password);
      //Random class using randomLong as seed
      rnd = new Random(randomLong);
      randoms = new byte[password.length()];
      //Array of random bytes generated with rnd
      rnd.nextBytes(randoms);

      System.out.println(randomNumber(password));

      String cryped = encrypt(password);
      String decryped = decrypt(cryped);

      System.out.println(cryped);
      System.out.println(decryped);
   }

   /**
    * Encrypts the password.
    */
   private String encrypt(String password) {
      char[] chars = password.toCharArray();      
      for (int i = 0; i < chars.length; i++) {
         chars[i] = (char) (chars[i] + randoms[i]);
      }
      return String.valueOf(chars);
   }

   /**
    * Decrypts an allready encryped password.
    */
   private String decrypt(String crypted) {
      char[] chars = crypted.toCharArray();
      for (int i = 0; i < chars.length; i++) {
         chars[i] = (char) (chars[i] - randoms[i]);
      }
      return String.valueOf(chars);
   }

   /**
    * Finds a random number BASED ON PASSWORD
    */
   private long randomNumber(String password)
   {
      char[] chars = password.toCharArray();
      long number = 0;
      for (char c : chars) {
         number += c;
      }
      number *= chars.length;
      return number;
   }
}
packagemain;
导入java.util.Random;
公共班机{
公共静态void main(字符串[]args){
//我们将玩这根绳子
新干线(“1234567890abc”);
}
私有随机rnd;
私有字节[]随机数;
/**
*启动RNG
*打印测试结果
*/
公用主(字符串密码){
//由密码生成的随机长密码
long randomLong=随机数(密码);
//使用randomLong作为种子的随机类
rnd=新随机(随机长);
randoms=新字节[password.length()];
//使用rnd生成的随机字节数组
rnd.下一个字节(随机);
System.out.println(随机数(密码));
字符串cryped=加密(密码);
String decryped=解密(cryped);
系统输出打印LN(cryped);
System.out.println(取消键入);
}
/**
*加密密码。
*/
私有字符串加密(字符串密码){
char[]chars=password.toCharArray();
for(int i=0;i

该类是用Java编写的,但任何人都应该可读。

在多个方面都被严重破坏

  • 你的钥匙是64位的,今天有点小。但这是你现在最不担心的
  • 我看到一个非加密PRNG。您需要使用加密PRNG
  • 您正在重用流密码中的密钥。流密码因难以正确使用而臭名昭著。在这种操作模式下,其基本行为类似于PRNG生成的一次性焊盘。一旦在这种模式下重复使用密钥,密码就会被破坏。
    假设攻击者知道
    encrypt(p1)
    encrypt(p2)
    。然后他可以计算
    encrypt(p1)-encrypt(p2)
    ,这与
    p1-p2
    相同
  • 您的有效密钥大小远小于64位。字符串中字符的总和为
  • 不要在现实生活中重新发明自己的密码(这是一种练习吗?),即使专家也会犯错。使用经过公开审查的东西
  • java随机数生成器在加密方面不安全。有了足够长的文本进行加密,就会出现允许各种信息泄漏的模式,包括泄露密码(但请参见第三点)和明文
  • 您可以使用密码为随机数生成器设定种子。这是一个标准(而且很好)的想法,但您使用的是一种对排列不变性的算法!i、 e.您的加密将“sinecure”和“不安全”或其他密码视为等效密码(可能还有其他密码)。对于最多16个字母的强密码,并且没有超过255的代码点,最高可达种子为255*16*16=65280;但可能性更小,因为有比这更低的种子是无法获得的。在我的键盘上,bruteforcing只显示了9734个不同的密码种子,这些密码完全由键盘可写字符组成,不包括长度最多为16个字符的换行符(我算95个);每个字母的熵小于1位
  • CodeInChaos在他的回答中还有一些额外的观察:你正在使用一个流密码(甚至更难做到正确!)。您还对密码进行了加密,这表明您可能在寻找哈希而不是加密函数(或者这只是一个示例?)
  • 顺便说一下,如果你想储存密码;不要-甚至没有加密!为什么要看索尼的惨败;您可能会被黑客攻击,您可能会丢失密码数据库,并且攻击者可能知道您的加密密钥。相反,使用标准的、最佳实践的密码散列(如果可能的话,最好使用一个标准的已有组件)。这样的系统应至少使用安全散列,如sha1或更好;密码应该是单独加盐的(盐可以明文存储),并且这个过程应该在计算上花费很大,以使暴力变得不吸引人。有关详细信息,请参阅

  • 为什么不把代码放在这里?为了可读性,指数化。。。那是家庭作业吗?如果不是,为什么不使用java.security.*?它不是家庭作业,我也不必在任何地方使用它。当然不是想打破你的泡沫,但人们花了一生的时间来编写加密安全软件。在现实世界中,当有人粗暴地强迫你的数据库时,创建一个55行的类并不能减少它。如其他人所说,如果您有兴趣学习,请使用现有类或读入开源加密包。是否可以将您的代码从pastebin复制到此处?这样一来,当pastebin过期时,你的问题就有意义了……据我所知,什么都没有:+1当你写下那1000'000个数字时,我想我会写一个粗体forcer:结果是,最多16个字符,有9642种不同的可能性:非常有限:-)brute强制他的密码存储的主要问题是如何识别您是否成功。我假设他实际上没有将其用于密码存储,因为他在那里有解密功能,而这只适用于他从