ASP. NET has no magic-encryption and decryption of ASP. NET Identity, and identity encryption and decryption
The previous article introduced how to use Identity in ASP. net mvc to Implement User Registration, logon, and authentication. These functions are related to user information security, and the importance of data security is always the first. For the registration and login functions, the password and other user information should be securely submitted to the server in the form of a form, the most suitable method is to use HTTPS (if there are conditions or security requirements, all requests should be based on HTTPS. This Chapter does not introduce HTTPS ), at the time of registration, the user's password should be encrypted and stored in the database, including user name verification during logon. The password is also encrypted in plaintext before matching. For identity authentication, the user information string generated by the server must be encrypted to protect user information and ensure that the current server (or cluster) can recognize it.
This chapter introduces the encryption and decryption involved in Identity from the following points:
● Common encryption methods
●. Net Implementation of Common encryption methods
● Encryption and decryption of Identity user passwords
● Process of Identity Information Processing
● Encryption and decryption of MachineKey
● User-Defined Identity authentication (based on MachineKey)
Common encryption methods
The encryption methods commonly used in software are divided into two types, one is that the ciphertext can be decrypted back to the plaintext, and the other is that the ciphertext cannot be decrypted.
This type of encryption that can be decrypted is mainly through symmetric encryption algorithms and asymmetric encryption algorithms, such as DES, AES, and RSA. Their main feature is that they require "keys" for encryption and decryption, if the key is disclosed, security issues may occur.
However, this type of undecrypted data is extracted by using one-way Hash algorithms such as MD5 and SHA1, which has achieved the "encryption" effect, however, this method also has a defect that, as long as the algorithms are the same, the encryption results for the same string are the same. When a hacker obtains the user database, although the user password is encrypted, however, hackers can create a "rainbow table" to crack the password. Therefore, another algorithm that adds "salt" and adds special "salt" to ensure the inconsistent encryption of the same string of the same HASH algorithm, however, if "salt" is leaked, hackers can still crack the attack, so there is a "random salt ".
Reference: http://mp.weixin.qq.com/s? _ Biz = MzIwMzg1ODcwMw ==& mid = 2247486407 & amp; idx = 1 & amp; sn = 51dfbce7d04ab6faeb0f5a27a5bdcbf8 & source = 41 # wechat_redirect
. Net Implementation of Common encryption methods
The. Net System. Security. Cryptography namespace contains the encryption and decryption types. Some of these types are based on managed code, and some are based on Windows APIs.
. The encryption and decryption type of. Net is located in system. dll assembly (Note: you can install System through nuget on a non-windows platform. security. cryptography. primitives. dll. security. under the Cryptography namespace. Encryption algorithms are classified into three types:
● Symmetric encryption algorithms: AES and DES
● Asymmetric encryption algorithms: RSA and ECDH
● HASH algorithm: SHA1, MD5, etc.
In addition, it should be noted that. Net implements symmetric encryption and HASH algorithms using data stream-oriented methods. This design can combine multiple encryption algorithms in tandem to perform operations on the "Data Stream" (this is a bit similar to the owin middleware method, data Encryption can be dynamically processed as needed ).
Microsoft official documentation on the use of encryption algorithms is recommended:
● Data Protection: Aes
● Data Integrity: HMACSHA256 and HMACSHA512
● Digital Signature: ECDsa and RSA
● Key Exchange: ECDiffieHellman and RSA
● Random Number Generation: RNGCryptoServiceProvider
● Generate a Key using a password (using the random salt Hash algorithm): Rfc2898DeriveBytes
More Information Reference documents: https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model
Encryption and decryption of Identity user passwords
A user's password is generally a short string containing various characters. The purpose of encryption is to prevent the user's password from being stored in the database in plain text, plaintext storage password can cause system developers or operators to threaten user information security and user information security caused by hacker attack data leakage. Therefore, the encrypted password is encrypted using an undecrypted Hash algorithm ".
According to the analysis in the previous article, the User Creation and password matching are completed through the UserManager type in Identity:
1. register the called code:
2. logon call code (Note: SignInManager is located in the Microsoft. AspNet. Identity. Owin program set ):
However, we can see from the source code that SignInManager actually uses UserManager to match the password:
3. therefore, according to the above analysis, user password encryption is completed in UserManager, And the UserManager definition has an IPasswordHasher interface, this interface defines Hash encryption of passwords and password verification after Hash:
The default Implementation of IPasswordHasher is PasswordHasher:
The Code shows that PassswordHasher is encrypted and verified by a static method named Crypto:
Hash computing:
Hash Verification:
The following conclusions can be drawn from the Crypto code:
1. the default password encryption in Identity is based on the Rfc2898 algorithm (the algorithm that calculates the hash value through random salt and set the number of iterations ).
2. The length of salt in the algorithm is 16 bits, and the number of iterations is 1000 (Note: each time Rfc2898DeriveBytes type is instantiated, a random array is created based on the length of salt. Rfc2898DeriveBytes's GetBytes algorithm is not described here. If you are interested, refer to the documentation and source code ).
3. During encryption, Identity Concatenates the salt and the encrypted result. The first 16 pieces of data are the encrypted result after the salt.
4. the "decryption" of the password is actually to get the first 16 digits of the data to get the salt through the encrypted result, and then Hash the input password and the salt, then compare whether the two Hash results are the same (note: the Hash algorithm cannot be decrypted ).
To change or expand the User Password Encryption Algorithm in Identity, you only need to implement a new IPasswordHasher and replace it when creating the UserManager instance.
Note: In fact, if the hacker obtains the above data, it can still crack the password. However, because the salt is random, it is more troublesome to crack large volumes of data, in this way, even if the data is leaked, there is time to remedy it. Therefore, Rfc2898 is a common password encryption method.
Process of Identity Information Processing
The user Identity information of Identity is much more complex than the password, because the password is only a string and it is easy to encrypt and decrypt a string. However, the Identity information of Identity is actually an AuthenticationTicket instance:
So how does Identity process this user Identity information instance?
1. first, we know that Identity is passed through the app. the UseCookieAuthentication method adds a middleware of the CookieAuthenticationMiddleware type to the pipeline. From the source code analysis, we can see that the middleware actually creates an internal type named CookieAuthenticationHandler, this type is used to obtain and verify the Cookie during the request, verify the failed redirect, and write the Cookie in response.
The Cookie encryption and decryption code is as follows:
Decryption: first obtain the Cookie value, and then return an AuthenticationTicket instance through the Unprotect method of TicketDataFormat:
Encryption: The AuthenticationTicket instance is converted to an encrypted string using the TicketDataFormat Protect method.
2. Identity mainly processes user Identity information through TicketDataFormat. From the code above, we can see that TicketDataFormat comes from Options. The Options here is actually the CookieAuthenticationOptions parameter in the app. UseCookieAuthentication method:
The default value of TicketDataFormat is created in the constructor. It requires a protector (Note: Protector is actually a component for encryption and decryption, which will be explained later in this chapter)
3. Responsibilities of TicketDataFormat:
Because TicketDataFormat is inherited from the SecureDataFormat type, and only the parameters passed into the base class are hardcoded In the constructor, the function is actually implemented by the Base class:
Responsibilities 1:Data is "protected". the serialization tool is used to serialize generic TData (here TData is actually the AuthenticationTicket type), and then the serialized binary data is encrypted through the encryption component, finally, the binary data is converted into a Base64Url string through the encoder. The Code is as follows:
Pay attention to the following two points:
1 ). the serializer is hardcoded by the TicketDataFormat constructor. Its actual type is TicketSerializer (for serialization, it is actually a memory instance in a program, it is saved in binary data, XML, Json, etc., and then deserialized into a previous memory instance using the data. Here, TicketSerializer is a binary serializer):
2 ). the difference between an encoder named Base64Url and a Base64 encoder is that because Base64 strings may contain special characters such as slash (/), these symbols cannot be correctly identified in the url, therefore, Base64Url performs special processing on these characters:
Responsibilities 2:The "Data Encryption" is actually the protection function. In turn, the Base64Url string is first decoded into binary data, then the binary data is decrypted, and finally the decrypted data is deserialized:
This chapter focuses on data encryption and decryption, so protector is the focus. Here, protector is created through IAppBulider from the code above:
As analyzed in the previous article, the core of Owin is actually a dictionary. Therefore, what you get through Owin should be stored in the dictionary:
AppBuilder initialization code:
According to the above analysis, if no Special Data Protector is specified, Identity uses MachineKeyDataProtector as the default data protector.
Note:
Identity Authentication principle in Identity is actually that after the Cookie is successfully decrypted and deserialized into an AuthenticationTicket instance, the Identity that passes Identity authentication (the IsAuthenticated attribute in this Identity is true) information is added to the context of the HTTP request. The access control that requires authentication in MVC is determined by the IsAuthenticated attribute of Identity in the request context.
Encryption and decryption of MachineKey
. Net has a component named MachineKey, which is used for Forms to verify user information, View State of asp.net, and encryption and verification of cross-process session State data. add the following configuration file in the config file to the MachineKey encryption and decryption, Authentication Algorithm and Its Key configuration, details can refer to the document: https://msdn.microsoft.com/en-us/library/w8h3skw9 (v = vs.100 ). aspx
The above analysis shows that Identity uses MachineKeyDataProtector as the Data Protector, while MachineKeyDataProtector actually uses MachineKey:
Note: Due to complicated MachineKey-related code, this article only introduces some of its main objects and encryption and decryption processes:
Main related objects of MachineKey:
● AspNetCryptoServiceProvider (internal type): ASP. NET uses it to obtain suitable encryption components.
● MachineKeySection: used to indicate the configuration information of the MachineKey.
● MachineKeyCryptoAlgorithmFactory (internal type): The MachineKey encryption algorithm factory. Depending on MachineKeySection, you can obtain the encryption algorithm type from the configuration file.
● MachineKeyMasterKeyProvider (internal type): the key provider, depending on MachineKeySection, can obtain key information from the configuration file.
● MachineKeyDataProtectorFactory (internal type): Data Protection factory, used to create a custom encryption/Decryption type (the configuration file can use the custom encryption algorithm through the alg: algorithm_name method ).
● Purpose (internal type): Used to Generate Keys for encryption and Verification Based on encryption purposes. Identity is used for User_MacineKey_Protect, and User_MacineKey_Protect is used for User. machineKey. protect for special purposes: "Microsoft. owin. security. cookies. cookieAuthenticationMiddleware "," ApplicationCookie "," v1 "(data comes from source code analysis ). In other words, if the keys are the same, but the encryption purposes are different, the keys actually used for encryption and decryption are different.
For the definition of Purpose, it can be seen from the definition that different functions, such as Forms verification, role information, and the Purpose of a series of Components in WebForm are different.
● NetFXCryptoService (internal type): the encryption and decryption service component used by MachineKey on the. Net platform. It is also the Identity information encryption and decryption component used in Identity.
The following code uses the NetFXCryptoService encryption and decryption algorithm. The algorithm consists of two parts: data encryption and decryption and data integrity verification:
Encryption:
1 public byte [] Protect (byte [] clearData) // claerData is the binary data to be encrypted 2 {3 byte [] buffer4; 4 using (SymmetricAlgorithm algorithm = this. _ cryptoAlgorithmFactory. getEncryptionAlgorithm () // obtain the encryption algorithm through the factory. In fact, it is to use the default or 5 {6 algorithm, such as AES specified in the configuration file. key = this. _ encryptionKey. getKeyMaterial (); // Purpose obtains the encryption key from the configuration file and derives the real key based on the actual Purpose. 7 if (this. _ predictableIV) 8 {9 algorithm. IV = CryptoUtil. createPredictableIV (clearData, algorithm. blockSize); 10} 11 else12 {13 algorithm. generateIV (); 14} 15 byte [] iV = algorithm. IV; 16 using (MemoryStream stream = new MemoryStream () 17 {18 stream. write (iV, 0, iV. length); 19 using (ICryptoTransform transform = algorithm. createEncryptor () 20 {21 using (CryptoStream stream2 = new CryptoStream (stream, transform, CryptoStreamMode. write) 22 {23 stream2.Write (clearData, 0, clearData. length); 24 stream2.FlushFinalBlock (); 25 using (KeyedHashAlgorithm algorithm2 = this. _ cryptoAlgorithmFactory. getValidationAlgorithm () // an algorithm used by the factory to obtain data verification. this algorithm is configured in the configuration file, such as 26 {27 algorithm2.Key = this. _ validationKey. getKeyMaterial (); // Purpose verifies the key obtained through the configuration file and derives the real key 28 byte [] buffer = algorithm2.ComputeHash (stream. getBuffer (), 0, (int) stream. length); 29 stream. write (buffer, 0, buffer. length); 30 buffer4 = stream. toArray (); 31} 32} 33} 34} 35} 36 return buffer4; 37}View Code
Decryption (Anti-encryption process ):
1 public byte [] Unprotect (byte [] protectedData) 2 {3 byte [] buffer3; 4 using (using ricalgorithm algorithm = this. _ cryptoAlgorithmFactory. getEncryptionAlgorithm () 5 {6 algorithm. key = this. _ encryptionKey. getKeyMaterial (); 7 using (KeyedHashAlgorithm algorithm2 = this. _ cryptoAlgorithmFactory. getValidationAlgorithm () 8 {9 algorithm2.Key = this. _ validationKey. getKeyMaterial (); 10 int offset = algo Rithm. blockSize/8; 11 int num2 = algorithm2.HashSize/8; 12 int count = (protectedData. length-offset)-num2; 13 if (count <= 0) 14 {15 return null; 16} 17 byte [] buffer = algorithm2.ComputeHash (protectedData, 0, offset + count ); 18 if (! CryptoUtil. buffersAreEqual (protectedData, offset + count, num2, buffer, 0, buffer. length) 19 {20 buffer3 = null; 21} 22 else23 {24 byte [] dst = new byte [offset]; 25 Buffer. blockCopy (protectedData, 0, dst, 0, dst. length); 26 algorithm. IV = dst; 27 using (MemoryStream stream = new MemoryStream () 28 {29 using (ICryptoTransform transform = algorithm. createDecryptor () 30 {31 using (CryptoStream stream2 = new CryptoStream (stream, transform, CryptoStreamMode. write) 32 {33 stream2.Write (protectedData, offset, count); 34 stream2.FlushFinalBlock (); 35 buffer3 = stream. toArray (); 36} 37} 38} 39} 40} 41} 42 return buffer3; 43}View Code custom Identity authentication (based on MachineKey)
In this example, the Cookie value generated by logon is obtained in the Action Method of the Controller, decrypted and deserialized into an AuthenticactionTicket instance:
Code:
1 public ActionResult Index () 2 {3 // 1. obtain the encrypted user information string from the Cookie 4 var cookieStr = this. httpContext. request. cookies [". aspNet. applicationCookie "]. value. toString (); 5 // 2. convert the user information string to binary data in Base64Url format. 6 var cookieBytes = TextEncodings. base64Url. decode (cookieStr); 7 // 3. the converted binary data is decrypted through the MachineKey (Note: The MachinKey uses User_MacineKey_Protect by default for the main purpose, 8 // provided by the Owin Cookie verification middleware for special purposes) 9 var result = MachineKey. unprotect (cookieBytes, 10 new string [] {"Microsoft. owin. security. cookies. cookieAuthenticationMiddleware ", 11" ApplicationCookie ", 12" v1 "}); 13 TicketSerializer ticketSerializer = new TicketSerializer (); 14 // 4. deserializes the decrypted binary data to AuthenticationTicket instance 15 var ticket = ticketSerializer. deserialize (result); 16 17 return View (); 18}View Code
Running result after Logon:
Note: The MachineKey can be used to change the encryption and decryption algorithms and keys for data verification through the configuration file. This configuration file can be implemented through the "computer key" function of IIS:
Summary
This chapter describes the encryption algorithms commonly used in software development. based on the Application Introduction In. Net, the process and method of encryption and decryption of user passwords and user information in Identity are introduced. The encryption and decryption of user passwords is relatively simple, as a complex object instance, user information also needs to be serialized and deserialized before encryption and decryption, it is also known that the protection of user information is not only encrypted, but also comes with the data integrity verification function. Data security is a very important topic, and Identity authentication is the default ASP.. net mvc provides features provided by an independent authentication template. An application template that can be created in one minute provides such complex user data security protection functions. net.
In addition to Identity, this chapter also introduces data protection and authentication methods. If Identity is not used, you can still use the concept to create a data protection solution that meets your own needs.
Refer:
Https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model
Https://msdn.microsoft.com/en-us/library/ff648652.aspx
Https://www.rfc-editor.org/rfc/rfc2898.txt
Https://www.codeproject.com/articles/16645/asp-net-machinekey-generator
Http://www.cnblogs.com/happyhippy/archive/2006/12/23/601353.html
Http://mp.weixin.qq.com? _ Biz = MzIwMzg1ODcwMw ==& mid = 2247486407 & amp; idx = 1 & amp; sn = 51dfbce7d04ab6faeb0f5a27a5bdcbf8 & source = 41 # wechat_redirect
Link: http://www.cnblogs.com/selimsong/p/7771875.html
ASP. NET has no magic-directory