代码之家  ›  专栏  ›  技术社区  ›  Hector

如何在Android客户端和服务器端应用程序之间安全地发送密码?

  •  2
  • Hector  · 技术社区  · 6 年前

    我当前的Android应用程序要求用户使用用户名和密码登录。

    如何保护我的用户密码,以便服务器端可以识别/验证每个用户?

    我目前正在尝试使用Jasypt库作为如下所示:-

    ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();
    passwordEncryptor.setAlgorithm("SHA-1");
    passwordEncryptor.setPlainDigest(true);
    String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
    ...
    if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword)) {
      // correct!
    } else {
      // bad login!
    }
    

    然而,我的服务器端是用.NET编写的,据我所知,Jasypt文档中的密码加密程序使用随机salt。

    我的所有webservices都有HTTPS端点,这能保证在交换访问令牌时没有人能“看到”我的用户密码吗?

    3 回复  |  直到 6 年前
        1
  •  1
  •   ucMedia    6 年前

    你必须小心你的所作所为。考虑实现一个通用的双因素密钥共享算法,例如 TOTP
    一个非常不寻常但非常好的做法是 . 当然,这并不能阻止黑客登录用户的帐户,但它阻止他们获取可能重用的纯文本密码。
    我建议更改电子邮件和密码是在 公式,因此需要电子邮件/SMS确认。
    最后,当您这样做时,非常重要的一点是,登录发生的连接是安全的,例如https/tls。

        2
  •  1
  •   Daniel    6 年前

    一个好的解决方案是避免使用传统的电子邮件/密码方法进行身份验证,并采用这里的另一个答案建议的OTP或一次性密码。

    考虑一下用户体验:在移动设备上键入电子邮件和密码既麻烦又烦人,而且很尴尬。那他们还得记住密码?西方世界的普通人每天大概要使用10到15个应用程序,我们想向他们的人类记忆库征税,让他们在拥挤的地铁列车上尴尬地在手机上输入另一个密码?

    尽管这看起来很难拼凑起来,但考虑一下一次性密码。使用它,用户输入一个电话号码作为识别令牌。

    理论上,每个用户都有自己独特的电话号码,用户很容易记住。既然你的用户是在他们的安卓设备上,到目前为止是有意义的,对吧?而且没有尴尬的电子邮件和密码输入。

    在他们输入电话号码后,我们会给他们发一个4到6位数的代码到移动设备上。用户在应用程序中输入该代码,从而证明他们是绑定电话号码的设备的所有者。

    OTP相对于电子邮件/密码的好处是它只需要用户很少的内存。是的,它甚至比OAuth更好,因为如果用户从未通过移动浏览器登录到Gmail帐户或Github帐户呢?然后他们又回到了移动设备的电子邮件/密码式身份验证。

    一次性密码是用户友好的。

    如何让我的服务器端代码与我发送的哈希用户密码匹配?

    对,所以一次性密码技术一直是IMO雄心勃勃的项目。

    因此,我们需要保存用户应该输入到设备中的代码,以便在将来的某个时候进行比较。当你生成一个代码时,把它保存到Firebase,这样在将来的某个时候你就可以回到Firebase说电话号码为212-555-1212的用户刚刚给你发送了代码1234,这是正确的代码吗?

    因此,Firebase使用OTP的方式是可以将代码存储在Firebase中。不过,挑战实际上是向用户发送一个代码。这是一条真正的短信。为了解决这个问题,你不能单独使用Firebase,你可以集成非常流行的Twilio。Twilio是通过手机短信与用户进行交互的,因此我们可以利用Twilio向用户发送代码。

    所以所有的JSON存储和所有反映用户身份的信息,都可以保存在Firebase上。

    但这个问题还有一部分我没有回答:

    是否可以识别/验证每个用户?

    好的,你需要比较一下服务器上的代码。它不可能是Firebase,因为Firebase只是一个数据存储,它是一个存储JSON数据的地方,它不能让我们运行自定义代码。

    那么,您是否编写了一个用于代码比较的服务器?我们不想在用户的设备上进行这种比较。

    那么我们在哪里生成代码呢?我们知道使用Firebase数据存储来存储代码,但是我们如何生成它呢?

    对于Google云功能来说,这是一个很好的工作。

        3
  •  1
  •   MRShafiee Emad Mahouti    5 年前

    如果您使用Https(TLS),则任何拦截网络的人都无法访问您的密码。

    您还可以使用okhttpcertificatepiner将Https(TLS)证书固定到您的连接,以避免中间人攻击。

        4
  •  -1
  •   Ishwor Khanal    6 年前

    首先,您的服务器有什么身份验证和授权机制来请求api端点?(是双因素认证吗?它是基于承载令牌(授权类型用户名和密码)的吗?是不记名代币吗( grant-type access-token

    第二,正如您所提到的,服务器编程是基于.Net的,但是您能否更具体地说明您的服务层(Api)是用WebApi 2还是OData编写的?

    那么只有在你的终端,即在Android移动应用中,才能根据服务器的要求,推动身份验证和授权机制,与api端点进行通信。

    grant-type password (GET, POST, DELETE, PUT) 我使用改造客户端实现如下:

     public Retrofit getRetrofitClient() {
    
        // first add the authorization header
        OkHttpClient mOkClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request newRequest  = chain.request().newBuilder()
                        .addHeader("Authorization", "XXXXXXXXXXXX")
                        .build();
                return chain.proceed(newRequest);
            }
        }).build();
    
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .client(mOkClient)
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
                    .build();
        }
        return retrofit;
    }
    

      public interface LoginService {
    
        @POST("/api/token")
        @FormUrlEncoded
        Call<TokenModel> getToken(@Field("username") String username,
                                  @Field("password") String password,
                                  @Field("grant_type") String grantType);
    
    }
    

    现在我可以在每个请求中使用这个令牌来与服务器通信。我不需要在公共互联网上传输用户名和密码,我只使用令牌,它有24小时到期(因为服务器已经实现了这个令牌到期日期)。

    希望能帮助您理解cleint(Android移动应用)和服务器之间的认证和授权机制。

    推荐文章