Snowflake Java UDF报错:无法找到支持AES_256/GCM/NoPadding的提供者
问题
我有一个用Groovy编写的外部加密函数,尝试在Snowflake中使用Java编写解密UDF时出现错误,错误信息如下:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting "AES_256/GCM/NoPadding" at java.base/javax.crypto.Cipher.getInstance(Cipher.java:565) at function_handler_0//utility.decrypt(InlineCode.java:32)
Java解密函数代码:
private static final int KEY_LENGTH = 256; private static final int ITERATION_COUNT = 10000; //65536; private static final byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // private static GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); public static String decrypt(String strToDecrypt, String secretKey, String salt) { try { GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); byte[] encryptedData = Base64.getMimeDecoder().decode(strToDecrypt); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES"); //cipher creation and decryption Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, parameterSpec); byte[] decryptedText = cipher.doFinal(encryptedData); return new String(decryptedText, "UTF-8"); } catch (Exception e) { // Handle the exception properly e.printStackTrace(); return null; } }
该解密函数在Snowflake外部运行正常,求解决建议。
解决建议
- 修改Cipher算法名称格式:Snowflake内置Java环境不支持
AES_256/GCM/NoPadding这种带密钥长度的命名,改用标准格式AES/GCM/NoPadding即可。密钥长度由生成的SecretKeySpec决定(已生成256位AES密钥),算法名称无需额外指定长度。修改后的代码行:Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); - 显式指定加密提供者:Snowflake默认加密提供者可能缺少AES-256 GCM支持,可指定使用SunJCE提供者:
若仍无效,可尝试引入BouncyCastle作为加密提供者,需将其jar包上传至Snowflake阶段,并在创建UDF时声明依赖。Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); - 核对加密参数一致性:确保Groovy加密时使用的IV与当前全0IV完全一致,同时GCM标签长度(当前为128位)也和加密端保持一致,避免参数不匹配引发的间接错误。
- 统一字符编码:代码中
salt.getBytes()需显式指定UTF-8编码,与Groovy加密端保持一致:KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(StandardCharsets.UTF_8), 65536, 256);
内容的提问来源于stack exchange,提问作者LeoG
相关产品推荐
相关产品推荐

