在App Engine上安全地保存p12文件的位置? [英] Where to keep p12 file securely on App Engine?

查看:150
本文介绍了在App Engine上安全地保存p12文件的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



Google没有描述什么是保存这个文件的最佳实践。



我可以使用WEB-INF目录来存储文件吗?它将成为源代码的一部分,并与密码一起打开。



这里有什么最佳实践?或其他方法?

-



性能如何?一遍又一遍加载文件是否高效? App Engine是否会自动缓存跨越通话的文件(在同一实例上)?或者我需要使用servlet加载一次文件,然后以某种方式将其保存在静态变量中?是否有更好的方法来实现这一点,比如将文件存储在数据存储记录中,然后将其保存在memcache中?这种方法有多安全?可能不是好的,对吗?

解决方案

在App Engine中,文件存储周围存在许多不常见的安全限制。我发现安全存储资源的最佳地点是使用捆绑包本身。如果您使用的是由appengine maven框架项目生成的默认Maven设置,这与将文件放置在相应资源目录中一样简单



一旦p12位于正确的位置,您需要使用类加载器的GetResourceAsStream函数加载它。然后,在构建GoogleCredentials时,请不要使用记录的setServiceAccountPrivateKeyFromP12File()函数,而应使用setServiceAccountPrivateKey()函数并传入您刚刚构建的PrivateKey。

此外,您很可能不希望将这些功能用于实时appengine实例,因为Appengine已经为您提供了一种更容易使用的AppIdentityCredentials功能因此您可能需要检测您的应用程序是否处于生产模式,并且仅在使用本地主机进行测试时才使用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)
返回新的AppIdentityCredential(scopes);
else
{

GoogleCredential凭证;

尝试{
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());

凭证=新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();
返回null;
} catch(Exception e){
e.printStackTrace();
返回null;
}

返回凭证;

}

}


On App Engine, I need a p12 file to create signed URLs:

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

Google does not describe what are best practices about keeping this file.

Can I use the WEB-INF directory to store the file? It would then be part of the source code and kept together with the password to open it.

What are best practices here? Or other approaches?

--

What about performance? Is it efficient to load the file over and over again? Does App Engine automatically cache the file across calls (on the same instance)? Or will I need to load the file once using a servlet and then keep it in a static variable somehow? Are there better ways to achieve this, like storing the file in a datastore record and then keep it in memcache? How secure would that approach be? Probably no good, right?

解决方案

In App Engine specifically there are a number of unusual security limitations around File storage. I have found the best place to store resources securely is by using the bundle itself. If you're using the default Maven setup as produced by the appengine maven skeleton project this is as simple as placing the file inside of the appropriate resources directory

Once the p12 is in the correct location, you'll need to load it using the class loader's GetResourceAsStream function. Then when building the GoogleCredentials, don't use the documented setServiceAccountPrivateKeyFromP12File() function, but instead use the setServiceAccountPrivateKey() function and pass in the PrivateKey that you just constructed.

Additionally, you will most likely not want to use any of this functionality with a live appengine instance since Appengine already provides you with a much easier to use AppIdentityCredentials function in that case so you will probably want to detect whether or not your app is in production mode and only use the ServiceAccount when testing using localhost.

Putting all of these functions together yields the following function which works for me:

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;

      }

  }

这篇关于在App Engine上安全地保存p12文件的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆