Хорошим местом для начала является JavaDocs . Они охватывают это:
Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
- Вызов метода экземпляра нулевого объекта.
- Доступ или изменение поля нулевого объекта.
- Выполнение длины null, как если бы это был массив.
- Доступ или изменение слотов с нулевым значением, как если бы это был массив.
- Бросать нуль, как если бы это было значение Throwable.
Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.
blockquote>Также, если вы попытаетесь использовать нулевую ссылку с
synchronized
, который также выдаст это исключение, за JLS :SynchronizedStatement: synchronized ( Expression ) Block
blockquote>
- В противном случае, если значение выражения равно null,
NullPointerException
.Как это исправить?
Итак, у вас есть
NullPointerException
. Как вы это исправите? Возьмем простой пример, который выдаетNullPointerException
:public class Printer { private String name; public void setName(String name) { this.name = name; } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer(); printer.print(); } }
Идентифицирует нулевые значения
. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:
Exception in thread "main" java.lang.NullPointerException at Printer.printString(Printer.java:13) at Printer.print(Printer.java:9) at Printer.main(Printer.java:19)
Здесь мы видим, что исключение выбрано в строке 13 (в методе
printString
). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, чтоs
имеет значение null, а вызов методаlength
на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когдаs.length()
удаляется из метода.Трассировка, где эти значения взяты из
Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что
s
передается сprintString(name)
в методеprint()
, аthis.name
- null.Трассировка, где эти значения должны быть установлены
Где установлен
this.name
? В методеsetName(String)
. С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. Этого достаточно, чтобы дать нам решение: добавить вызов
printer.setName()
перед вызовомprinter.print()
.Другие исправления
Переменная может иметь значение по умолчанию (и
setName
может помешать ему установить значение null):private String name = "";
Либо метод
printString
может проверить значение null например:printString((name == null) ? "" : name);
Или вы можете создать класс, чтобы
name
всегда имел ненулевое значение :public class Printer { private final String name; public Printer(String name) { this.name = Objects.requireNonNull(name); } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer("123"); printer.print(); } }
См. также:
Я все еще не могу найти проблему
Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).
Хешируют их использующий что-то как поставщик SHA256 и когда необходимо бросить вызов, хешировать вход от пользователя и видеть, соответствуют ли два хеша.
byte[] data = System.Text.Encoding.ASCII.GetBytes(inputString);
data = new System.Security.Cryptography.SHA256Managed().ComputeHash(data);
String hash = System.Text.Encoding.ASCII.GetString(data);
обратимые пароли Отъезда действительно ужасная модель.
Edit2: Я думал, что мы просто говорили о пограничной аутентификации. Уверенный существуют случаи, где Вы хотите зашифровать пароли для других вещей, которые должны быть обратимыми, но должна быть блокировка с 1 путем сверху всего этого (за очень немногими исключениями).
я обновил алгоритм хеширования, но для самой лучшей силы Вы хотите оставаться частная соль и добавить это к Вашему входу прежде хеширование его . Вы сделали бы это снова, когда Вы выдерживаете сравнение. Это добавляет другой слой, делающий его еще тяжелее для кого-то для инвертирования.
Также рассмотрите "соление" Вашего хеша (не кулинарное понятие!). В основном это означает добавлять некоторый случайный текст к паролю перед хешированием его.
Для хранения хэшей пароля:
a) Генерируют случайное соленое значение:
byte[] salt = new byte[32];
System.Security.Cryptography.RNGCryptoServiceProvider.Create().GetBytes(salt);
b) Добавляют соль к паролю.
// Convert the plain string pwd into bytes
byte[] plainTextBytes = System.Text UnicodeEncoding.Unicode.GetBytes(plainText);
// Append salt to pwd before hashing
byte[] combinedBytes = new byte[plainTextBytes.Length + salt.Length];
System.Buffer.BlockCopy(plainTextBytes, 0, combinedBytes, 0, plainTextBytes.Length);
System.Buffer.BlockCopy(salt, 0, combinedBytes, plainTextBytes.Length, salt.Length);
Хеш c) объединенный пароль & соль:
// Create hash for the pwd+salt
System.Security.Cryptography.HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA256Managed();
byte[] hash = hashAlgo.ComputeHash(combinedBytes);
d) Добавляют соль к результирующему хешу.
// Append the salt to the hash
byte[] hashPlusSalt = new byte[hash.Length + salt.Length];
System.Buffer.BlockCopy(hash, 0, hashPlusSalt, 0, hash.Length);
System.Buffer.BlockCopy(salt, 0, hashPlusSalt, hash.Length, salt.Length);
Хранилище e) результат в Вашем пользователе хранят базу данных.
Этот подход означает, что Вы не должны сохранить соль отдельно и затем повторно вычислить хеш с помощью соленого значения и значения незашифрованного пароля, полученного от пользователя.
Редактирование : Поскольку необработанная вычислительная мощность становится более дешевой и быстрее, значение хеширования - или соление хешей - уменьшилось. у Jeff Atwood есть превосходное обновление 2012 года слишком длинный для повторения в целом здесь, который указывает:
Это (использование соленых хешей) обеспечит иллюзию безопасности больше, чем какая-либо фактическая безопасность. Так как Вам нужны и соль и в выбор хеш-алгоритма генерировать хеш и проверить хеш, маловероятно, что взломщик имел бы один, но не другой. Если Вы были скомпрометированы до такой степени, что у взломщика есть Ваша база данных пароля, разумно принять их или иметь или мочь получить Вашу секретную, скрытую соль.
первое правило безопасности состоит в том, чтобы всегда принимать и планировать худшее. Необходимо ли использовать соль, идеально случайную соль для каждого пользователя? Несомненно, это - определенно хорошая практика, и по крайней мере это позволяет Вам снять неоднозначность двух пользователей, у которых есть тот же пароль. Но в эти дни, одни только соли больше не могут сохранять Вас от человека, готового потратить несколько тысяч долларов на аппаратные средства видеокарты, и если Вы думаете, что они могут, Вы быть в беде.
Это - то, что требуется сделать:
OurKey.SetValue("Password", StringEncryptor.EncryptString(textBoxPassword.Text));
OurKey.GetValue("Password", StringEncryptor.DecryptString(textBoxPassword.Text));
можно сделать это с этим следующие классы. Этот класс является универсальным классом, клиентская конечная точка. Это включает МОК различных алгоритмов шифрования с помощью Ninject.
public class StringEncryptor
{
private static IKernel _kernel;
static StringEncryptor()
{
_kernel = new StandardKernel(new EncryptionModule());
}
public static string EncryptString(string plainText)
{
return _kernel.Get<IStringEncryptor>().EncryptString(plainText);
}
public static string DecryptString(string encryptedText)
{
return _kernel.Get<IStringEncryptor>().DecryptString(encryptedText);
}
}
Этот следующий класс является ninject классом, который позволяет Вам вводить различные алгоритмы:
public class EncryptionModule : StandardModule
{
public override void Load()
{
Bind<IStringEncryptor>().To<TripleDESStringEncryptor>();
}
}
Это - интерфейс, который любой алгоритм должен реализовать для шифрования/дешифрования строк:
public interface IStringEncryptor
{
string EncryptString(string plainText);
string DecryptString(string encryptedText);
}
Это - реализация с помощью алгоритма TripleDES:
public class TripleDESStringEncryptor : IStringEncryptor
{
private byte[] _key;
private byte[] _iv;
private TripleDESCryptoServiceProvider _provider;
public TripleDESStringEncryptor()
{
_key = System.Text.ASCIIEncoding.ASCII.GetBytes("GSYAHAGCBDUUADIADKOPAAAW");
_iv = System.Text.ASCIIEncoding.ASCII.GetBytes("USAZBGAW");
_provider = new TripleDESCryptoServiceProvider();
}
#region IStringEncryptor Members
public string EncryptString(string plainText)
{
return Transform(plainText, _provider.CreateEncryptor(_key, _iv));
}
public string DecryptString(string encryptedText)
{
return Transform(encryptedText, _provider.CreateDecryptor(_key, _iv));
}
#endregion
private string Transform(string text, ICryptoTransform transform)
{
if (text == null)
{
return null;
}
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
byte[] input = Encoding.Default.GetBytes(text);
cryptoStream.Write(input, 0, input.Length);
cryptoStream.FlushFinalBlock();
return Encoding.Default.GetString(stream.ToArray());
}
}
}
}
можно посмотреть мой ролик и загрузить код для этого в: http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in-nhibernateactive-record-video.html
Одна опция состояла бы в том, чтобы сохранить хеш (SHA1, MD5) пароля вместо пароля в виде открытого текста, и каждый раз, когда Вы хотите видеть, хорош ли пароль, просто сравните его с тем хешем.
, Если Вы должны защитить устройство хранения данных (например, для пароля, который Вы будете использовать для соединения с сервисом), тогда проблема более сложна.
, Если бы это только для аутентификации, тогда было бы достаточно использовать хеш.
Если бы Вы хотите быть в состоянии дешифровать пароль, я думаю, что самый легкий путь состоял бы в том, чтобы использовать DPAPI (пользовательский режим хранилища) для шифрования/дешифрования. Таким образом, Вы не должны играть с ключами шифрования, сохранить их где-нибудь или твердый код их в Вашем коде - в обоих случаях кто-то может обнаружить их путем изучения реестра, пользовательских настроек или использования Отражателя.
Иначе использование хеширует SHA1, или MD5 как другие сказали здесь.
Если это - пароль, используемый для аутентификации Вашим приложением, то хешируйте пароль, как другие предполагают.
при хранении паролей для внешнего ресурса Вы будете часто хотеть быть в состоянии предложить пользователю эти учетные данные и дать ему возможность сохранить их надежно. Windows предоставляет Учетным данным UI (CredUI) с этой целью - существует много образцов, показывающих, как использовать это в.NET, включая этот на MSDN.
При необходимости в больше, чем это, например, защищая строку подключения (для соединения с базой данных), проверяет этот статья , поскольку это предоставляет лучшую "возможность" для этого.
ответ Oli также хорош, поскольку он показывает, как можно создать хеш для строки.
.. СЕТЬ предоставляет cryptographics услуги в классе, содержавшемся в Системе. Безопасность. Пространство имен криптографии.
Вместо того, чтобы шифровать/дешифровать, необходимо передавать пароль через алгоритм хеширования, md5/sha512, или подобные. То, что Вы идеально сделали бы, хешировать пароль и сохранить хеш, тогда когда пароль необходим, Вы хешируете запись и сравниваете записи. Пароль никогда не будет тогда "дешифровываться", просто хешироваться и затем сравниваться.
Как сказанный ligget78, DPAPI был бы хорошим способом пойти для хранения паролей. Проверьте класс ProtectedData на MSDN, например, использование.