7

I'm building an application that takes in login credentials (username and password). I want to encrypt before sending the data to the server. I would really appreciate if someone can provide some insight on the most common method or best practice for password encryption in Swift.

firefly
  • 201
  • 1
  • 3
  • 11
  • you can store it in keychain http://www.raywenderlich.com/92667/securing-ios-data-keychain-touch-id-1password – Dan Beaulieu Jan 10 '16 at 04:39
  • 1
    Just use TLS https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/SecureNetworkCommunicationAPIs/SecureNetworkCommunicationAPIs.html – pvg Jan 10 '16 at 04:40
  • What about base64 http://cocoadev.com/BaseSixtyFour – lojals Jan 10 '16 at 04:41
  • 1
    Why do you want to encrypt it? if you want to store it in local, you should just put it to keychain. If you dont want to store plain text in your server, you can hash it and store hash value. – Surely Jan 10 '16 at 04:42
  • 1
    I think there is some data missing here - how does the API expect you to authenticate? API token? Basic auth? Digest auth? I think we need a little more information before giving you and answer that is helpful to your problem. – galois Jan 10 '16 at 04:44
  • @zp_x I'm storing password to the server. Can you provide an example on password hashing in Swift. – firefly Jan 10 '16 at 04:45
  • Beware of using base64, as suggested above - that does not provide any security! – Jacek Lampart Jan 10 '16 at 05:20
  • hi, this provides a code to do hash in swift using CommonCrypto: http://stackoverflow.com/questions/24099520/commonhmac-in-swift – Surely Jan 10 '16 at 05:59
  • I voted to close as **unclear what you're asking**, because it seems that you even you don't really know what you want. Any recommendation about some technology depends on the use case. What do you want to do with the credentials on the server? Do you want to authenticate the user? Do you want to store the credentials to access some other service from the server or from the client? Either way you at the very least need a secure channel that you can build up with TLS. – Artjom B. Jan 10 '16 at 11:37
  • @ArtjomB. I apologize if my question is unclear. The app performs basic user authentication; basically, it sends `username` and `password` to the server, and the server response with the `uid` if the user exists (the server should be able to decrypt the password for verification). My concern was that I need to encrypt the user credentials before forwarding to the server for security purposes. – firefly Jan 10 '16 at 13:21
  • @firefly I see. In this case you need to send the credentials unaltered to the server through a secure channel (TLS). The server itself will need to hash the password with a random salt and many iterations (think PBKDF2, scrypt, bcrypt or Argon2). If you would hash the password on the client, then this hash becomes the new password and the server is none the wiser. – Artjom B. Jan 10 '16 at 13:43
  • @ArtjomB. Thank you so much for helping. One more question.. Isn't it the preferred practice to not send raw data (like password) to the server? Unless the secure channel guarantees secure transmission. – firefly Jan 10 '16 at 13:54
  • 2
    It's common practice to send the raw username and password to the server over a secure channel. If you would try to recreate a secure transmission from CommonCrypto or similar things, then you will most likely make some mistakes that would completely destroy any security. There may be attacks that are even applicable if the crypto-primitives are well chosen. Replay attacks come to mind, but there are others. It's easiest to use an existing standard which is implemented everywhere. You could additionally encrypt the data before writing it to the secure channel, but that won't give you much. – Artjom B. Jan 10 '16 at 14:04

3 Answers3

1

If you really need to encrypt the credentials in Swift, you could use https://github.com/krzyzanowskim/CryptoSwift

But it would be best to just POST them to the server via https - that way, they will be encrypted/decrypted for you.

Jacek Lampart
  • 1,741
  • 13
  • 25
  • So, sending raw data via https and let the server perform encryption/decryption? – firefly Jan 10 '16 at 17:09
  • 2
    Actually, if you send data via https, it is encrypted on the client, and decrypted on the server. All this happens transparently, without having to explicitly encrypt anything in your code. – Jacek Lampart Jan 10 '16 at 17:51
  • 4
    Whaaat? The day your users come to know that you are transferring passwords as plain text will probably be the day your startup dies. Trust that is once lost can never be gotten back. – John Smith Oct 21 '16 at 12:15
  • 4
    This is a terrible answer. Never, ever rely on https encryption to secure plain text passwords. ALWAYS encrypt your users passwords. – Brian Corbin Mar 31 '17 at 19:20
  • @BrianCorbin would you care to elaborate? – Jacek Lampart Mar 31 '17 at 19:23
  • @JacekLampart Sure. First off, sorry if that came off a bit douchey, not my intention. Second, I'd like to clarify my statement.. encryption/decryption is totally viable via https, it's hashing the pwds on the client side that you want to make sure you do. Apologies again for the outburst, I misread "encryption" as "hashing" in the above post in a heat of passionate user security 101. – Brian Corbin Mar 31 '17 at 19:44
  • 1
    Agreed on both points. OP was asking about sending the data to the server, not storing it on the client (in which case, as many people have mentioned, encryption is essential.) – Jacek Lampart Mar 31 '17 at 19:52
  • @ Sava Mazăre -Don't copy! Give credit where Credit is due!The day your users come to know that you are transferring passwords as plain text will probably be the day your startup dies. Trust that is once lost can never be gotten bac. by Mugunth Kumar 3/1/2012 http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/ – Brian Bird Apr 03 '17 at 23:20
0

You can use Keychain Wrapper to store username and password for your app. you can download the wrapper from here: https://github.com/jrendel/SwiftKeychainWrapper

They have instruction on how to use that in their Readme

Sanjan Piya
  • 247
  • 2
  • 8
0

==> our Objective-C code (using a NSString category) can be directly translated to Swift (using a String extension).

  extension String {

func sha1() -> String {
    let data = self.dataUsingEncoding(NSUTF8StringEncoding)!
    var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
    CC_SHA1(data.bytes, CC_LONG(data.length), &digest)
    let output = NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))
    for byte in digest {
        output.appendFormat("%02x", byte)
    }
    return output as String
}}println("Hello World".sha1())
Akash
  • 461
  • 2
  • 14