【问题标题】:How to implement request decryption and response encryption in Play application?如何在 Play 应用中实现请求解密和响应加密?
【发布时间】:2015-08-07 01:35:30
【问题描述】:

给定

trait CipherService {
  def decryptData(data: Array[Byte])(implicit ec: ExecutionContext): Future[DecryptionError \/ Array[Byte]
  def encryptEncrypt(data: Array[Byte)(implicit ec: ExecutionContext): Future[EncryptionError \/ Array[Byte]]
}

如何使用EssentialFilter 实现请求解密和响应加密?感觉就像我被 EnumerateeIteratee API 所困。

【问题讨论】:

    标签: scala encryption playframework playframework-2.0 iterate


    【解决方案1】:

    当您达到字节块的限制时,Iteratees 和 Enumeratees 几乎是可行的方法。加密是一种非常低级的操作,而且很难做到正确,因此这些工具同样是低级的、小而精确的。

    由于加密和解密数据很难做到正确,大多数 Web 框架都依赖 HTTPS,而不是在应用层实现它。

    如果您使用的是 HTTP,则使用 nginx 和根据 Bettercrypto.org 配置的 OpenSSL:https://www.playframework.com/documentation/2.3.x/ConfiguringHttps

    如果您在内部使用安全性并希望通过网络加密数据,则应在传输模式下使用 ipsec。

    【讨论】:

    • 我们已经使用 HTTPS,但我们对 HTTP 顶部的一些标头和正文进行了自定义加密。
    • 好的——你能做的(虽然这仍然是实验性的)是在 2.4.x 中使用 Reactive Streams API:playframework.com/documentation/2.4.x/…
    • 我昨天想通了。很快就会发布答案。
    【解决方案2】:
    trait CipherService {
      def decryptData(data: Array[Byte])(implicit ec: ExecutionContext): Future[DecryptionError \/ Array[Byte]]
      def encryptData(data: Array[Byte])(implicit ec: ExecutionContext): Future[EncryptionError \/ Array[Byte]]
    }
    
    trait BodyEncryptionFilter extends EssentialFilter with Results {
    
      import play.api.libs.concurrent.Execution.Implicits._
    
      val cipher: CipherService
    
      def apply(next: EssentialAction): EssentialAction = new EssentialAction {
        override def apply(requestHeader: RequestHeader): Iteratee[Array[Byte], Result] =
          Iteratee.consume[Array[Byte]]().mapM { encryptedBody => // Collect body bytes
            cipher.decryptData(encryptedBody) // Decrypt data
              .toEitherT   // Monad transformer
              .flatMapF { decryptedBody =>
                Enumerator(decryptedBody).run(next(requestHeader)) // Feed decrypted data to filter/action chain
                  .flatMap { result => // Here is the action result
                    result.body.run(Iteratee.consume[Array[Byte]]()) //Collect result body data
                      .flatMap { body =>
                        cipher.encryptData(body) // Ecnrypt body data
                          .toEitherT
                          .map { encryptedBody =>
                            result.copy(body = Enumerator(encryptedBody)) // Wrap it with Enumerator and copy result
                          }
                          .leftMap(_ => BadRequest("Encryption error")) // You will probably want proper error handling
                          .merge
                      }
                  }
                .map(_.right)
              }
              .leftMap(_ => BadRequest("Encryption error"))
              .merge
          }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 2019-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多