哪里可以在App Engine上安全保存p12文件?

Oli*_*ler 5 security google-app-engine signing

在App Engine上,我需要一个p12文件来创建签名的URL:

https://developers.google.com/storage/docs/accesscontrol#Signing-Strings

Google没有说明保留此文件的最佳做法.

我可以使用WEB-INF目录存储文件吗?然后它将成为源代码的一部分并与密码保持在一起以打开它.

这里的最佳做法是什么?还是其他方法?

-

性能怎么样?一遍又一遍地加载文件是否有效?App Engine是否自动在调用之间缓存文件(在同一实例上)?或者我需要使用servlet加载文件一次,然后以某种方式将其保存在静态变量中?有没有更好的方法来实现这一点,例如将文件存储在数据存储区记录中,然后将其保存在memcache中?这种方法有多安全?可能不好,对吧?

Ove*_*Tim 6

特别是在App Engine中,文件存储存在许多不寻常的安全限制.我发现安全存储资源的最佳位置是使用捆绑包本身.如果您正在使用由appengine maven骨架项目生成的默认Maven设置,这就像将文件放在相应资源目录中一样简单

资源目录结构

一旦p12位于正确的位置,您将需要使用类加载器的GetResourceAsStream函数加载它.然后在构建GoogleCredentials时,不要使用文档化的setServiceAccountPrivateKeyFromP12File()函数,而是使用setServiceAccountPrivateKey()函数并传入刚刚构造的PrivateKey.

此外,您很可能不希望将任何此功能与实时的appengine实例一起使用,因为在这种情况下,Appengine已经为您提供了更容易使用的AppIdentityCredentials功能,因此您可能希望检测您的应用是否在生产中模式,仅在使用localhost进行测试时使用ServiceAccount.

将所有这些功能放在一起产生以下功能,对我有用:

public static HttpRequestInitializer getDefaultCredentials() throws IOException
  {
      List<String> scopes = Arrays.asList(new String[] {DEVSTORAGE_FULL_CONTROL});
      if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production)
          return new AppIdentityCredential(scopes);
      else
      {

          GoogleCredential credential;

          try {
              String p12Password = "notasecret";

              ClassLoader classLoader = ServiceUtils.class.getClassLoader();

              KeyStore keystore = KeyStore.getInstance("PKCS12");
              InputStream keyFileStream = classLoader.getResourceAsStream("key.p12");

              if (keyFileStream == null){
                  throw new Exception("Key File Not Found.");
              }

              keystore.load(keyFileStream, p12Password.toCharArray());
              PrivateKey key = (PrivateKey)keystore.getKey("privatekey", p12Password.toCharArray());

              credential = new GoogleCredential.Builder()
                      .setTransport(HTTP_TRANSPORT)
                      .setJsonFactory(JSON_FACTORY)
                      .setServiceAccountId("YOUR_SERVICE_ACCOUNT_EMAIL@developer.gserviceaccount.com")
                      .setServiceAccountPrivateKey(key)
                      .setServiceAccountScopes(scopes)
                      .build();
          } catch (GeneralSecurityException e) {
              e.printStackTrace();
              return null;
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }

          return credential;

      }

  }
Run Code Online (Sandbox Code Playgroud)